@jhits/plugin-newsletter 0.0.8 → 0.0.9

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.
Files changed (75) hide show
  1. package/data/locales/en/common.json +12 -0
  2. package/data/locales/nl/common.json +12 -0
  3. package/data/locales/sv/common.json +12 -0
  4. package/dist/api/email-utils.d.ts +6 -0
  5. package/dist/api/email-utils.d.ts.map +1 -0
  6. package/dist/api/email-utils.js +134 -0
  7. package/dist/api/handler.d.ts +2 -47
  8. package/dist/api/handler.d.ts.map +1 -1
  9. package/dist/api/handler.js +2 -523
  10. package/dist/api/handlers/index.d.ts +12 -0
  11. package/dist/api/handlers/index.d.ts.map +1 -0
  12. package/dist/api/handlers/index.js +11 -0
  13. package/dist/api/handlers/newsletters.d.ts +11 -0
  14. package/dist/api/handlers/newsletters.d.ts.map +1 -0
  15. package/dist/api/handlers/newsletters.js +250 -0
  16. package/dist/api/handlers/send-newsletter.d.ts +8 -0
  17. package/dist/api/handlers/send-newsletter.d.ts.map +1 -0
  18. package/dist/api/handlers/send-newsletter.js +206 -0
  19. package/dist/api/handlers/settings.d.ts +11 -0
  20. package/dist/api/handlers/settings.d.ts.map +1 -0
  21. package/dist/api/handlers/settings.js +304 -0
  22. package/dist/api/handlers/subscribers.d.ts +10 -0
  23. package/dist/api/handlers/subscribers.d.ts.map +1 -0
  24. package/dist/api/handlers/subscribers.js +96 -0
  25. package/dist/api/handlers/upload.d.ts +7 -0
  26. package/dist/api/handlers/upload.d.ts.map +1 -0
  27. package/dist/api/handlers/upload.js +32 -0
  28. package/dist/api/handlers/welcome-email.d.ts +13 -0
  29. package/dist/api/handlers/welcome-email.d.ts.map +1 -0
  30. package/dist/api/handlers/welcome-email.js +142 -0
  31. package/dist/api/router.d.ts.map +1 -1
  32. package/dist/api/router.js +45 -6
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +42 -16
  35. package/dist/lib/email/EmailRenderer.d.ts.map +1 -1
  36. package/dist/lib/email/EmailRenderer.js +3 -7
  37. package/dist/lib/i18n.d.ts +16 -0
  38. package/dist/lib/i18n.d.ts.map +1 -0
  39. package/dist/lib/i18n.js +60 -0
  40. package/dist/state/EditorContext.d.ts +3 -1
  41. package/dist/state/EditorContext.d.ts.map +1 -1
  42. package/dist/state/EditorContext.js +1 -5
  43. package/dist/state/reducer.js +5 -5
  44. package/dist/types/newsletter.d.ts +1 -0
  45. package/dist/types/newsletter.d.ts.map +1 -1
  46. package/dist/views/CanvasEditor/CanvasEditorView.d.ts +4 -2
  47. package/dist/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -1
  48. package/dist/views/CanvasEditor/CanvasEditorView.js +73 -10
  49. package/dist/views/CanvasEditor/EditorHeader.d.ts +6 -1
  50. package/dist/views/CanvasEditor/EditorHeader.d.ts.map +1 -1
  51. package/dist/views/CanvasEditor/EditorHeader.js +66 -11
  52. package/dist/views/CanvasEditor/components/EditorSidebar.d.ts +6 -2
  53. package/dist/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -1
  54. package/dist/views/CanvasEditor/components/EditorSidebar.js +3 -3
  55. package/dist/views/CanvasEditor/hooks/useNewsletterLoader.d.ts +1 -1
  56. package/dist/views/CanvasEditor/hooks/useNewsletterLoader.d.ts.map +1 -1
  57. package/dist/views/CanvasEditor/hooks/useNewsletterLoader.js +41 -5
  58. package/dist/views/NewsletterEditor.d.ts +4 -2
  59. package/dist/views/NewsletterEditor.d.ts.map +1 -1
  60. package/dist/views/NewsletterEditor.js +2 -2
  61. package/dist/views/NewsletterManager.d.ts.map +1 -1
  62. package/dist/views/NewsletterManager.js +137 -8
  63. package/dist/views/components/SendNewsletterModal.d.ts +18 -0
  64. package/dist/views/components/SendNewsletterModal.d.ts.map +1 -0
  65. package/dist/views/components/SendNewsletterModal.js +107 -0
  66. package/dist/views/components/SmtpSettingsModal.d.ts +10 -0
  67. package/dist/views/components/SmtpSettingsModal.d.ts.map +1 -0
  68. package/dist/views/components/SmtpSettingsModal.js +145 -0
  69. package/dist/views/components/TestEmailModal.d.ts +10 -0
  70. package/dist/views/components/TestEmailModal.d.ts.map +1 -0
  71. package/dist/views/components/TestEmailModal.js +99 -0
  72. package/package.json +20 -9
  73. package/templates/logo.png +0 -0
  74. package/templates/test-email.hbs +221 -0
  75. package/templates/welcome-email-legacy.hbs +35 -0
@@ -0,0 +1,12 @@
1
+ {
2
+ "testEmail": {
3
+ "title": "SMTP Configuration Verified",
4
+ "greeting": "Hello,",
5
+ "description": "This is a test email to verify that your SMTP configuration is working correctly.",
6
+ "successTitle": "Success!",
7
+ "successMessage": "Your SMTP settings are configured correctly.",
8
+ "recipientLabel": "Email sent to:",
9
+ "footerText": "This is an automated test email from",
10
+ "ignoreText": "If you did not expect to receive this email, you can safely ignore it."
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "testEmail": {
3
+ "title": "SMTP-configuratie geverifieerd",
4
+ "greeting": "Hallo,",
5
+ "description": "Dit is een test e-mail om te verifiëren dat je SMTP-configuratie correct werkt.",
6
+ "successTitle": "Gelukt!",
7
+ "successMessage": "Je SMTP-instellingen zijn correct geconfigureerd.",
8
+ "recipientLabel": "E-mail verzonden naar:",
9
+ "footerText": "Dit is een automatische test e-mail van",
10
+ "ignoreText": "Als je deze e-mail niet verwacht, kun je hem negeren."
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "testEmail": {
3
+ "title": "SMTP-konfiguration verifierad",
4
+ "greeting": "Hej,",
5
+ "description": "Detta är ett testmeddelande för att verifiera att din SMTP-konfiguration fungerar korrekt.",
6
+ "successTitle": "Framgång!",
7
+ "successMessage": "Dina SMTP-inställningar är korrekt konfigurerade.",
8
+ "recipientLabel": "E-post skickat till:",
9
+ "footerText": "Detta är ett automatiskt testmeddelande från",
10
+ "ignoreText": "Om du inte förväntade dig detta e-postmeddelande kan du ignorera det."
11
+ }
12
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Email Utilities
3
+ */
4
+ import { NewsletterApiConfig } from '../types/newsletter';
5
+ export declare function sendWelcomeEmail(config: NewsletterApiConfig, email: string, language: string, host?: string): Promise<void>;
6
+ //# sourceMappingURL=email-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-utils.d.ts","sourceRoot":"","sources":["../../src/api/email-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,mBAAmB,EAAsB,MAAM,qBAAqB,CAAC;AAqC9E,wBAAsB,gBAAgB,CAClC,MAAM,EAAE,mBAAmB,EAC3B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAoHf"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Email Utilities
3
+ */
4
+ 'use server';
5
+ import nodemailer from 'nodemailer';
6
+ import path from 'path';
7
+ import fs from 'fs';
8
+ import handlebars from 'handlebars';
9
+ import { GET_WELCOME_EMAIL_CONTENT } from './handlers/welcome-email';
10
+ async function getSmtpConfig(config) {
11
+ const dbConnection = await config.getDb();
12
+ const db = dbConnection.db();
13
+ const settings = db.collection('settings');
14
+ const smtpConfig = await settings.findOne({ key: 'smtp' });
15
+ if (smtpConfig && smtpConfig.host) {
16
+ return {
17
+ host: smtpConfig.host,
18
+ port: smtpConfig.port || 465,
19
+ user: smtpConfig.user,
20
+ password: smtpConfig.password,
21
+ from: smtpConfig.from,
22
+ fromName: smtpConfig.fromName || '',
23
+ logoUrl: smtpConfig.logoUrl || '',
24
+ };
25
+ }
26
+ return null;
27
+ }
28
+ export async function sendWelcomeEmail(config, email, language, host) {
29
+ const smtpConfig = await getSmtpConfig(config);
30
+ if (!smtpConfig)
31
+ return;
32
+ const { blocks, metadata } = await GET_WELCOME_EMAIL_CONTENT(undefined, config, language);
33
+ const isDutch = language === 'nl';
34
+ const isSwedish = language === 'sv';
35
+ const baseUrl = host
36
+ ? (host.includes('localhost') ? 'http' : 'https') + '://' + host
37
+ : config.baseUrl || 'https://bya.jorishummel.com';
38
+ const slugs = {
39
+ sv: '/avmälla',
40
+ nl: '/afmelden',
41
+ en: '/unsubscribe',
42
+ };
43
+ const slug = slugs[language] || slugs.en;
44
+ const unsubscribeUrl = `${baseUrl}${slug}?email=${encodeURIComponent(email)}`;
45
+ try {
46
+ const transporter = nodemailer.createTransport({
47
+ host: smtpConfig.host,
48
+ port: smtpConfig.port,
49
+ secure: smtpConfig.port === 465,
50
+ auth: {
51
+ user: smtpConfig.user,
52
+ pass: smtpConfig.password,
53
+ },
54
+ connectionTimeout: 10000,
55
+ });
56
+ let html;
57
+ let subject;
58
+ let logoAttachment = undefined;
59
+ let logoSrc = smtpConfig.logoUrl || `${baseUrl}/logo_black.svg`;
60
+ // If logoUrl is a data URL (base64), embed it as CID attachment
61
+ if (smtpConfig.logoUrl && smtpConfig.logoUrl.startsWith('data:')) {
62
+ const matches = smtpConfig.logoUrl.match(/^data:([^;]+);base64,(.+)$/);
63
+ if (matches) {
64
+ const mimeType = matches[1];
65
+ const base64Data = matches[2];
66
+ const ext = mimeType === 'image/png' ? 'png' : 'jpg';
67
+ logoAttachment = {
68
+ filename: `logo.${ext}`,
69
+ content: Buffer.from(base64Data, 'base64'),
70
+ cid: 'logo',
71
+ contentType: mimeType,
72
+ };
73
+ logoSrc = 'cid:logo';
74
+ }
75
+ }
76
+ if (blocks && blocks.length > 0) {
77
+ const { generateNewsletterEmailHtml } = await import('../lib/email/EmailRenderer');
78
+ html = generateNewsletterEmailHtml(blocks, { subject: metadata?.subject || '', previewText: metadata?.previewText || '' }, {
79
+ baseUrl,
80
+ locale: language,
81
+ logoUrl: logoSrc,
82
+ unsubscribeUrl,
83
+ footerText: `© ${new Date().getFullYear()} ${smtpConfig.fromName || 'Botanics & You'}`,
84
+ });
85
+ subject = metadata?.subject || (isDutch ? 'Welkom!' : isSwedish ? 'Välkommen!' : 'Welcome!');
86
+ }
87
+ else {
88
+ const legacyTemplatePath = path.join(process.cwd(), 'node_modules', '@jhits', 'plugin-newsletter', 'templates', 'welcome-email-legacy.hbs');
89
+ let templateContent;
90
+ if (fs.existsSync(legacyTemplatePath)) {
91
+ templateContent = fs.readFileSync(legacyTemplatePath, 'utf-8');
92
+ }
93
+ else {
94
+ const altPath = path.join(__dirname, '..', '..', '..', 'templates', 'welcome-email-legacy.hbs');
95
+ if (fs.existsSync(altPath)) {
96
+ templateContent = fs.readFileSync(altPath, 'utf-8');
97
+ }
98
+ else {
99
+ console.error('[NewsletterAPI] Legacy email template not found');
100
+ return;
101
+ }
102
+ }
103
+ const template = handlebars.compile(templateContent);
104
+ html = template({
105
+ fromName: smtpConfig.fromName || 'Botanics & You',
106
+ title: isDutch ? 'Fijn dat je er bent' : isSwedish ? 'Tack för att du är här' : "We're glad you're here",
107
+ message: isDutch
108
+ ? 'Bedankt dat je deel uitmaakt van de community. Wij geloven dat de natuur alles biedt wat we werkelijk nodig hebben.'
109
+ : isSwedish
110
+ ? 'Tack för att du är en del av vår community. Vi tror att naturen ger oss allt vi verkligen behöver.'
111
+ : 'Thank you for joining our community. We believe that nature provides everything we truly need.',
112
+ unsubscribeUrl,
113
+ unsubscribeText: isDutch ? 'Afmelden' : isSwedish ? 'Avanmälan' : 'Unsubscribe',
114
+ tagline: isDutch ? 'Natuurlijk verbonden' : isSwedish ? 'Naturligt ansluten' : 'Naturally connected',
115
+ currentYear: new Date().getFullYear(),
116
+ });
117
+ subject = isDutch ? 'Welkom bij Botanics & You' : isSwedish ? 'Välkommen till Botanics & You' : 'Welcome to Botanics & You';
118
+ }
119
+ await transporter.sendMail({
120
+ from: smtpConfig.fromName
121
+ ? `"${smtpConfig.fromName}" <${smtpConfig.from}>`
122
+ : smtpConfig.from,
123
+ to: email,
124
+ subject,
125
+ html,
126
+ ...(logoAttachment && {
127
+ attachments: [logoAttachment],
128
+ }),
129
+ });
130
+ }
131
+ catch (error) {
132
+ console.error('[NewsletterAPI] Failed to send welcome email:', error);
133
+ }
134
+ }
@@ -1,51 +1,6 @@
1
1
  /**
2
2
  * Newsletter API Handler
3
- * Handles all newsletter-related API requests
3
+ * Re-exports all handler functions from handlers folder
4
4
  */
5
- import { NextRequest, NextResponse } from 'next/server';
6
- import { NewsletterApiConfig } from '../types/newsletter';
7
- /**
8
- * GET /api/plugin-newsletter/subscribers - List all subscribers
9
- */
10
- export declare function GET_SUBSCRIBERS(req: NextRequest, config: NewsletterApiConfig): Promise<NextResponse>;
11
- /**
12
- * POST /api/plugin-newsletter/subscribers - Subscribe new email
13
- */
14
- export declare function POST_SUBSCRIBE(req: NextRequest, config: NewsletterApiConfig): Promise<NextResponse>;
15
- /**
16
- * GET /api/plugin-newsletter/subscribers/[email] - Get specific subscriber
17
- */
18
- export declare function GET_SUBSCRIBER(req: NextRequest, email: string, config: NewsletterApiConfig): Promise<NextResponse>;
19
- /**
20
- * DELETE /api/plugin-newsletter/subscribers/[email] - Unsubscribe/delete subscriber
21
- */
22
- export declare function DELETE_SUBSCRIBER(req: NextRequest, email: string, config: NewsletterApiConfig): Promise<NextResponse>;
23
- /**
24
- * GET /api/plugin-newsletter/settings - Get newsletter settings
25
- */
26
- export declare function GET_SETTINGS(req: NextRequest, config: NewsletterApiConfig): Promise<NextResponse>;
27
- /**
28
- * POST /api/plugin-newsletter/settings - Update newsletter settings
29
- */
30
- export declare function POST_SETTINGS(req: NextRequest, config: NewsletterApiConfig): Promise<NextResponse>;
31
- /**
32
- * GET /api/plugin-newsletter/newsletters - List all newsletters
33
- */
34
- export declare function GET_NEWSLETTERS(req: NextRequest, config: NewsletterApiConfig): Promise<NextResponse>;
35
- /**
36
- * GET /api/plugin-newsletter/newsletters/[slug] - Get specific newsletter
37
- */
38
- export declare function GET_NEWSLETTER(req: NextRequest, slug: string, config: NewsletterApiConfig): Promise<NextResponse>;
39
- /**
40
- * POST /api/plugin-newsletter/newsletters/new - Create new newsletter
41
- */
42
- export declare function POST_NEWSLETTER(req: NextRequest, config: NewsletterApiConfig): Promise<NextResponse>;
43
- /**
44
- * PUT /api/plugin-newsletter/newsletters/[slug] - Update existing newsletter
45
- */
46
- export declare function PUT_NEWSLETTER(req: NextRequest, slug: string, config: NewsletterApiConfig): Promise<NextResponse>;
47
- /**
48
- * DELETE /api/plugin-newsletter/newsletters/[slug] - Delete newsletter
49
- */
50
- export declare function DELETE_NEWSLETTER(req: NextRequest, slug: string, config: NewsletterApiConfig): Promise<NextResponse>;
5
+ export { GET_SUBSCRIBERS, POST_SUBSCRIBE, GET_SUBSCRIBER, DELETE_SUBSCRIBER, GET_SETTINGS, POST_SETTINGS, GET_NEWSLETTERS, GET_NEWSLETTER, POST_NEWSLETTER, PUT_NEWSLETTER, DELETE_NEWSLETTER, GET_WELCOME_EMAIL_STATUS, GET_WELCOME_EMAIL, POST_WELCOME_EMAIL, GET_SMTP_SETTINGS, POST_SMTP_SETTINGS, POST_TEST_EMAIL, POST_LOGO_UPLOAD, POST_SEND_NEWSLETTER, GET_NEWSLETTER_FOR_SEND, sendWelcomeEmail, } from './handlers';
51
6
  //# sourceMappingURL=handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/api/handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAkC,MAAM,qBAAqB,CAAC;AAI1F;;GAEG;AACH,wBAAsB,eAAe,CACjC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAwBvB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAChC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAgDvB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAChC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA2BvB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACnC,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA2BvB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAC9B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA2BvB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAC/B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAgCvB;AA8GD;;GAEG;AACH,wBAAsB,eAAe,CACjC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA2DvB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAChC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAiDvB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACjC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAyEvB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAChC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAuFvB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACnC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA4BvB"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/api/handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,eAAe,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,uBAAuB,EACvB,gBAAgB,GACnB,MAAM,YAAY,CAAC"}