@jhits/plugin-newsletter 0.0.14 → 0.0.16

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 (34) hide show
  1. package/dist/api/handlers/newsletters.d.ts.map +1 -1
  2. package/dist/api/handlers/newsletters.js +80 -24
  3. package/dist/api/handlers/send-newsletter.d.ts.map +1 -1
  4. package/dist/api/handlers/send-newsletter.js +31 -4
  5. package/dist/api/handlers/welcome-email.d.ts.map +1 -1
  6. package/dist/api/handlers/welcome-email.js +5 -2
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +3 -1
  9. package/dist/types/newsletter.d.ts +35 -0
  10. package/dist/types/newsletter.d.ts.map +1 -1
  11. package/dist/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -1
  12. package/dist/views/CanvasEditor/CanvasEditorView.js +28 -7
  13. package/dist/views/CanvasEditor/hooks/useNewsletterLoader.js +4 -4
  14. package/dist/views/NewsletterManager.d.ts.map +1 -1
  15. package/dist/views/NewsletterManager.js +96 -9
  16. package/dist/views/components/NewsletterCard.d.ts +16 -0
  17. package/dist/views/components/NewsletterCard.d.ts.map +1 -0
  18. package/dist/views/components/NewsletterCard.js +94 -0
  19. package/dist/views/components/NewsletterGrid.d.ts +16 -0
  20. package/dist/views/components/NewsletterGrid.d.ts.map +1 -0
  21. package/dist/views/components/NewsletterGrid.js +13 -0
  22. package/dist/views/components/SendNewsletterModal.js +1 -1
  23. package/package.json +1 -1
  24. package/src/api/handlers/newsletters.ts +94 -28
  25. package/src/api/handlers/send-newsletter.ts +33 -4
  26. package/src/api/handlers/welcome-email.ts +5 -2
  27. package/src/index.tsx +4 -1
  28. package/src/types/newsletter.ts +44 -0
  29. package/src/views/CanvasEditor/CanvasEditorView.tsx +28 -8
  30. package/src/views/CanvasEditor/hooks/useNewsletterLoader.ts +4 -4
  31. package/src/views/NewsletterManager.tsx +203 -20
  32. package/src/views/components/NewsletterCard.tsx +212 -0
  33. package/src/views/components/NewsletterGrid.tsx +48 -0
  34. package/src/views/components/SendNewsletterModal.tsx +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"newsletters.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/newsletters.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAkC,MAAM,wBAAwB,CAAC;AAc7F,wBAAsB,eAAe,CACjC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAiEvB;AAED,wBAAsB,cAAc,CAChC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAkDvB;AAED,wBAAsB,eAAe,CACjC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAqEvB;AAED,wBAAsB,cAAc,CAChC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAuEvB;AAED,wBAAsB,iBAAiB,CACnC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA8BvB"}
1
+ {"version":3,"file":"newsletters.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/newsletters.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAkC,MAAM,wBAAwB,CAAC;AAc7F,wBAAsB,eAAe,CACjC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAsFvB;AAED,wBAAsB,cAAc,CAChC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAuEvB;AAED,wBAAsB,eAAe,CACjC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAqEvB;AAED,wBAAsB,cAAc,CAChC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA+FvB;AAED,wBAAsB,iBAAiB,CACnC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA8BvB"}
@@ -29,6 +29,7 @@ export async function GET_NEWSLETTERS(req, config) {
29
29
  const skip = parseInt(searchParams.get('skip') || '0', 10);
30
30
  const sortBy = searchParams.get('sortBy') || 'updatedAt';
31
31
  const sortOrder = searchParams.get('sortOrder') || 'desc';
32
+ const language = searchParams.get('language') || 'en';
32
33
  const query = {};
33
34
  if (status) {
34
35
  query['publication.status'] = status;
@@ -49,19 +50,36 @@ export async function GET_NEWSLETTERS(req, config) {
49
50
  .limit(limit)
50
51
  .skip(skip)
51
52
  .toArray();
52
- const listItems = newsletterList.map((newsletter) => ({
53
- id: newsletter._id?.toString() || newsletter.id,
54
- title: newsletter.title,
55
- slug: newsletter.slug,
56
- status: newsletter.publication?.status || 'draft',
57
- subject: newsletter.metadata?.subject || '',
58
- scheduledDate: newsletter.publication?.scheduledDate,
59
- sentDate: newsletter.publication?.sentDate,
60
- authorId: newsletter.publication?.authorId,
61
- updatedAt: newsletter.updatedAt || newsletter.createdAt,
62
- recipientCount: newsletter.recipientCount,
63
- hidden: newsletter.hidden,
64
- }));
53
+ const primaryLanguage = 'en'; // Default primary
54
+ const listItems = newsletterList.map((newsletter) => {
55
+ const languages = newsletter.languages || {};
56
+ const newsletterPrimaryLang = newsletter.metadata?.lang || primaryLanguage;
57
+ // Get title (from subject) and subject from language-specific content
58
+ let title = newsletter.metadata?.subject || '';
59
+ if (languages[language]) {
60
+ title = languages[language].metadata?.subject || title;
61
+ }
62
+ else if (language !== newsletterPrimaryLang && languages[newsletterPrimaryLang]) {
63
+ // Fall back to primary language
64
+ title = languages[newsletterPrimaryLang].metadata?.subject || title;
65
+ }
66
+ return {
67
+ id: newsletter._id?.toString() || newsletter.id,
68
+ title: title || newsletter.title || 'Untitled',
69
+ slug: newsletter.slug,
70
+ status: newsletter.publication?.status || 'draft',
71
+ subject: title,
72
+ scheduledDate: newsletter.publication?.scheduledDate,
73
+ sentDate: newsletter.publication?.sentDate,
74
+ authorId: newsletter.publication?.authorId,
75
+ updatedAt: newsletter.updatedAt || newsletter.createdAt,
76
+ recipientCount: newsletter.recipientCount,
77
+ hidden: newsletter.hidden,
78
+ sendHistory: newsletter.sendHistory || [],
79
+ availableLanguages: Object.keys(languages),
80
+ languages,
81
+ };
82
+ });
65
83
  return NextResponse.json(listItems);
66
84
  }
67
85
  catch (error) {
@@ -75,6 +93,8 @@ export async function GET_NEWSLETTER(req, idOrSlug, config) {
75
93
  if (!userId) {
76
94
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
77
95
  }
96
+ const { searchParams } = new URL(req.url);
97
+ const language = searchParams.get('language') || 'en';
78
98
  const dbConnection = await config.getDb();
79
99
  const db = dbConnection.db();
80
100
  const collectionName = config.collectionName || 'newsletters';
@@ -84,21 +104,37 @@ export async function GET_NEWSLETTER(req, idOrSlug, config) {
84
104
  if (!newsletter) {
85
105
  return NextResponse.json({ error: 'Newsletter not found' }, { status: 404 });
86
106
  }
107
+ const languages = newsletter.languages || {};
108
+ const primaryLanguage = newsletter.metadata?.lang || 'en';
109
+ let blocks = newsletter.blocks || [];
110
+ let metadata = newsletter.metadata || {
111
+ subject: '',
112
+ previewText: '',
113
+ lang: 'en',
114
+ recipientFilter: { type: 'all' },
115
+ };
116
+ // If requested language has content, use it
117
+ if (languages[language]) {
118
+ blocks = languages[language].blocks || [];
119
+ metadata = { ...metadata, ...languages[language].metadata, lang: language };
120
+ }
121
+ else if (language !== primaryLanguage && languages[primaryLanguage]) {
122
+ // Copy from primary language if exists
123
+ blocks = languages[primaryLanguage].blocks || [];
124
+ metadata = { ...metadata, ...languages[primaryLanguage].metadata, lang: language };
125
+ }
87
126
  const result = {
88
127
  id: newsletter._id?.toString() || newsletter.id,
89
- title: newsletter.title,
128
+ title: metadata.subject || 'Untitled',
90
129
  slug: newsletter.slug,
91
- blocks: newsletter.blocks || [],
92
- metadata: newsletter.metadata || {
93
- subject: '',
94
- previewText: '',
95
- lang: 'en',
96
- recipientFilter: { type: 'all' },
97
- },
130
+ blocks,
131
+ metadata,
98
132
  publication: newsletter.publication || {
99
133
  status: 'draft',
100
134
  updatedAt: new Date().toISOString(),
101
135
  },
136
+ languages,
137
+ sendHistory: newsletter.sendHistory,
102
138
  createdAt: newsletter.createdAt || new Date().toISOString(),
103
139
  updatedAt: newsletter.updatedAt || new Date().toISOString(),
104
140
  version: newsletter.version,
@@ -175,6 +211,8 @@ export async function PUT_NEWSLETTER(req, idOrSlug, config) {
175
211
  if (!userId) {
176
212
  return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
177
213
  }
214
+ const { searchParams } = new URL(req.url);
215
+ const language = searchParams.get('language') || 'en';
178
216
  const body = await req.json();
179
217
  const { title, blocks, metadata, publication } = body;
180
218
  const errors = [];
@@ -197,15 +235,33 @@ export async function PUT_NEWSLETTER(req, idOrSlug, config) {
197
235
  if (!existing) {
198
236
  return NextResponse.json({ error: 'Newsletter not found' }, { status: 404 });
199
237
  }
238
+ // Preserve existing languages or initialize
239
+ const existingLanguages = existing.languages || {};
240
+ // Update the specific language content
241
+ const updatedLanguages = {
242
+ ...existingLanguages,
243
+ [language]: {
244
+ blocks: blocks || [],
245
+ metadata: {
246
+ subject: metadata.subject.trim(),
247
+ previewText: metadata.previewText?.trim() || '',
248
+ lang: language,
249
+ recipientFilter: metadata.recipientFilter || { type: 'all' },
250
+ },
251
+ },
252
+ };
253
+ // Set primary language if not set
254
+ const primaryLanguage = existing.metadata?.lang || language;
200
255
  const updateData = {
201
- title: finalTitle,
202
- blocks: blocks || [],
256
+ title: finalTitle, // Keep root title for backwards compatibility
257
+ blocks: blocks || [], // Keep blocks at root for backwards compatibility
203
258
  metadata: {
204
259
  subject: metadata.subject.trim(),
205
260
  previewText: metadata.previewText?.trim() || '',
206
- lang: metadata.lang || 'en',
261
+ lang: primaryLanguage,
207
262
  recipientFilter: metadata.recipientFilter || { type: 'all' },
208
263
  },
264
+ languages: updatedLanguages,
209
265
  publication: {
210
266
  ...existing.publication,
211
267
  status: publication?.status || existing.publication?.status || 'draft',
@@ -1 +1 @@
1
- {"version":3,"file":"send-newsletter.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/send-newsletter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AA4C7D,wBAAsB,oBAAoB,CACtC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA2LvB;AAED,wBAAsB,uBAAuB,CACzC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAuCvB"}
1
+ {"version":3,"file":"send-newsletter.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/send-newsletter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AA4C7D,wBAAsB,oBAAoB,CACtC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAwNvB;AAED,wBAAsB,uBAAuB,CACzC,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAuCvB"}
@@ -47,8 +47,21 @@ export async function POST_SEND_NEWSLETTER(req, idOrSlug, config) {
47
47
  if (!newsletter) {
48
48
  return NextResponse.json({ error: 'Newsletter not found' }, { status: 404 });
49
49
  }
50
- const blocks = newsletter.blocks || [];
51
- const metadata = newsletter.metadata || {};
50
+ // Get language-specific content if available
51
+ const languages = newsletter.languages || {};
52
+ const primaryLanguage = newsletter.metadata?.lang || 'en';
53
+ let blocks = newsletter.blocks || [];
54
+ let metadata = newsletter.metadata || {};
55
+ // If the requested language has content, use it
56
+ if (language && languages[language]) {
57
+ blocks = languages[language].blocks || [];
58
+ metadata = { ...metadata, ...languages[language].metadata };
59
+ }
60
+ else if (language !== primaryLanguage && languages[primaryLanguage]) {
61
+ // Fall back to primary language content
62
+ blocks = languages[primaryLanguage].blocks || [];
63
+ metadata = { ...metadata, ...languages[primaryLanguage].metadata };
64
+ }
52
65
  if (!blocks || blocks.length === 0) {
53
66
  return NextResponse.json({ error: 'Newsletter has no content' }, { status: 400 });
54
67
  }
@@ -102,11 +115,16 @@ export async function POST_SEND_NEWSLETTER(req, idOrSlug, config) {
102
115
  recipientCount = 1;
103
116
  }
104
117
  else {
105
- const subscriberList = await subscribers.find({ status: 'active' }).toArray();
118
+ // Filter subscribers by the selected language
119
+ const subscriberFilter = { status: 'active' };
120
+ if (language) {
121
+ subscriberFilter.language = language;
122
+ }
123
+ const subscriberList = await subscribers.find(subscriberFilter).toArray();
106
124
  recipientEmails = subscriberList.map((s) => s.email);
107
125
  recipientCount = recipientEmails.length;
108
126
  if (recipientCount === 0) {
109
- return NextResponse.json({ error: 'No active subscribers found' }, { status: 400 });
127
+ return NextResponse.json({ error: `No active subscribers found for language: ${language?.toUpperCase() || 'en'}` }, { status: 400 });
110
128
  }
111
129
  }
112
130
  const subject = metadata.subject || 'Newsletter';
@@ -147,12 +165,21 @@ export async function POST_SEND_NEWSLETTER(req, idOrSlug, config) {
147
165
  }
148
166
  }
149
167
  if (!isTest && successCount > 0) {
168
+ const sendHistoryEntry = {
169
+ language,
170
+ sentAt: new Date().toISOString(),
171
+ recipientCount: successCount,
172
+ authorId: userId,
173
+ };
150
174
  await newsletters.updateOne(filter, {
151
175
  $set: {
152
176
  'publication.status': 'sent',
153
177
  'publication.sentDate': new Date().toISOString(),
154
178
  'publication.recipientCount': successCount,
155
179
  updatedAt: new Date().toISOString(),
180
+ },
181
+ $push: {
182
+ sendHistory: sendHistoryEntry,
156
183
  }
157
184
  });
158
185
  }
@@ -1 +1 @@
1
- {"version":3,"file":"welcome-email.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/welcome-email.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAajF,wBAAsB,wBAAwB,CAC1C,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAsCvB;AAED,wBAAsB,iBAAiB,CACnC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CA6DvB;AAED,wBAAsB,kBAAkB,CACpC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAyDvB;AAED,wBAAsB,yBAAyB,CAC3C,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAAC,QAAQ,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAc1D"}
1
+ {"version":3,"file":"welcome-email.d.ts","sourceRoot":"","sources":["../../../src/api/handlers/welcome-email.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAajF,wBAAsB,wBAAwB,CAC1C,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAsCvB;AAED,wBAAsB,iBAAiB,CACnC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAgEvB;AAED,wBAAsB,kBAAkB,CACpC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC,CAyDvB;AAED,wBAAsB,yBAAyB,CAC3C,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,mBAAmB,EAC3B,QAAQ,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAAC,QAAQ,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAc1D"}
@@ -62,7 +62,7 @@ export async function GET_WELCOME_EMAIL(req, config) {
62
62
  title: 'Welcome Email',
63
63
  language,
64
64
  blocks: primaryContent.blocks,
65
- metadata: primaryContent.metadata,
65
+ metadata: { ...primaryContent.metadata, lang: language },
66
66
  languages,
67
67
  isCopy: true,
68
68
  copyFrom: primaryLanguage,
@@ -74,7 +74,10 @@ export async function GET_WELCOME_EMAIL(req, config) {
74
74
  title: 'Welcome Email',
75
75
  language,
76
76
  blocks: languages[language]?.blocks || primaryContent.blocks,
77
- metadata: languages[language]?.metadata || primaryContent.metadata,
77
+ metadata: {
78
+ ...(languages[language]?.metadata || primaryContent.metadata),
79
+ lang: language
80
+ },
78
81
  languages,
79
82
  isCopy: false,
80
83
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAOtD;;;GAGG;AACH,MAAM,WAAW,WAAW;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,yGAAyG;IACzG,YAAY,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACvC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,iDAAiD;QACjD,KAAK,EAAE,MAAM,CAAC;QACd,gDAAgD;QAChD,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACL;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,KAAK,EAAE,WAAW,2CA8Q1D;AAGD,OAAO,EAAE,gBAAgB,IAAI,KAAK,EAAE,CAAC;AAGrC,YAAY,EACR,KAAK,EACL,mBAAmB,EACnB,qBAAqB,EACrB,wBAAwB,EACxB,cAAc,EACd,iBAAiB,EACjB,eAAe,GAClB,MAAM,eAAe,CAAC;AAGvB,YAAY,EACR,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,GAC1B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAC9C,YAAY,EAAE,sBAAsB,EAAE,MAAM,QAAQ,CAAC;AAGrD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGpF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAOtD;;;GAGG;AACH,MAAM,WAAW,WAAW;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,yGAAyG;IACzG,YAAY,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACvC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,iDAAiD;QACjD,KAAK,EAAE,MAAM,CAAC;QACd,gDAAgD;QAChD,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACL;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,KAAK,EAAE,WAAW,2CAiR1D;AAGD,OAAO,EAAE,gBAAgB,IAAI,KAAK,EAAE,CAAC;AAGrC,YAAY,EACR,KAAK,EACL,mBAAmB,EACnB,qBAAqB,EACrB,wBAAwB,EACxB,cAAc,EACd,iBAAiB,EACjB,eAAe,GAClB,MAAM,eAAe,CAAC;AAGvB,YAAY,EACR,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,GAC1B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAC9C,YAAY,EAAE,sBAAsB,EAAE,MAAM,QAAQ,CAAC;AAGrD,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGpF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -130,10 +130,12 @@ export default function NewsletterPlugin(props) {
130
130
  apiData.metadata = apiData.metadata || {};
131
131
  apiData.metadata.lang = extraData.language;
132
132
  }
133
+ // Build URL with language param if provided
134
+ const langParam = extraData?.language ? `?language=${extraData.language}` : '';
133
135
  // If we have an id, try to update first
134
136
  if (originalId) {
135
137
  console.log('[NewsletterPlugin] Attempting to update newsletter with id:', originalId);
136
- const updateResponse = await fetch(`/api/plugin-newsletter/newsletters/${originalId}`, {
138
+ const updateResponse = await fetch(`/api/plugin-newsletter/newsletters/${originalId}${langParam}`, {
137
139
  method: 'PUT',
138
140
  headers: { 'Content-Type': 'application/json' },
139
141
  credentials: 'include',
@@ -38,6 +38,21 @@ export interface NewsletterPublicationData {
38
38
  authorId?: string;
39
39
  /** Last modified date */
40
40
  updatedAt?: string;
41
+ /** Recipient count for last send */
42
+ recipientCount?: number;
43
+ }
44
+ /**
45
+ * Send history entry for tracking sends per language
46
+ */
47
+ export interface SendHistoryEntry {
48
+ /** Language code sent to */
49
+ language: string;
50
+ /** When this was sent */
51
+ sentAt: string;
52
+ /** Number of recipients */
53
+ recipientCount: number;
54
+ /** Who sent it (author ID) */
55
+ authorId?: string;
41
56
  }
42
57
  /**
43
58
  * Newsletter Metadata
@@ -55,6 +70,19 @@ export interface NewsletterMetadata {
55
70
  value?: string;
56
71
  };
57
72
  }
73
+ /**
74
+ * Newsletter language content (blocks + metadata per language)
75
+ */
76
+ export interface NewsletterLanguageContent {
77
+ blocks: Block[];
78
+ metadata: NewsletterMetadata;
79
+ }
80
+ /**
81
+ * Languages object storing content per language
82
+ */
83
+ export interface NewsletterLanguages {
84
+ [key: string]: NewsletterLanguageContent;
85
+ }
58
86
  /**
59
87
  * Complete Newsletter Structure
60
88
  * This is the headless JSON structure stored in the database
@@ -70,6 +98,10 @@ export interface Newsletter {
70
98
  blocks: Block[];
71
99
  /** Publication data */
72
100
  publication: NewsletterPublicationData;
101
+ /** Send history for tracking multiple sends per language */
102
+ sendHistory?: SendHistoryEntry[];
103
+ /** Content per language (for multi-language newsletters) */
104
+ languages?: NewsletterLanguages;
73
105
  /** Additional metadata */
74
106
  metadata: NewsletterMetadata;
75
107
  /** Creation timestamp */
@@ -95,6 +127,9 @@ export interface NewsletterListItem {
95
127
  updatedAt: string;
96
128
  recipientCount?: number;
97
129
  hidden?: boolean;
130
+ sendHistory?: SendHistoryEntry[];
131
+ availableLanguages?: string[];
132
+ languages?: NewsletterLanguages;
98
133
  }
99
134
  /**
100
135
  * Newsletter Filter Options
@@ -1 +1 @@
1
- {"version":3,"file":"newsletter.d.ts","sourceRoot":"","sources":["../../src/types/newsletter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"newsletter.d.ts","sourceRoot":"","sources":["../../src/types/newsletter.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CanvasEditorView.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/CanvasEditorView.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,qBAAqB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,oDAAoD;IACpD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,qBAAqB,2CAwT1J"}
1
+ {"version":3,"file":"CanvasEditorView.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/CanvasEditorView.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,qBAAqB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,oDAAoD;IACpD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,qBAAqB,2CA4U1J"}
@@ -25,12 +25,23 @@ export function CanvasEditorView({ newsletterId, darkMode, backgroundColors: pro
25
25
  const [currentLanguage, setCurrentLanguage] = useState(locale || 'en');
26
26
  // Get registered blocks
27
27
  const registeredBlocks = useRegisteredBlocks();
28
- // Newsletter loading - use current language for welcome email (wait until language settings are loaded)
28
+ // Newsletter loading - wait for language settings to be loaded first
29
29
  const { isLoadingNewsletter } = useNewsletterLoader(newsletterId, state.newsletterId, (newsletter) => {
30
30
  helpers.loadNewsletter(newsletter);
31
- // Set current language from loaded newsletter metadata
32
- if (newsletter.metadata?.lang && !isWelcomeEmail) {
33
- setCurrentLanguage(newsletter.metadata.lang);
31
+ // Set current language from loaded newsletter (check both metadata.lang and top-level language)
32
+ const loadedLanguage = newsletter.metadata?.lang || newsletter.language;
33
+ if (loadedLanguage) {
34
+ setCurrentLanguage(loadedLanguage);
35
+ }
36
+ // Update available languages from newsletter's languages object (for regular newsletters)
37
+ if (!isWelcomeEmail && newsletter.languages && Object.keys(newsletter.languages).length > 0) {
38
+ const langs = Object.keys(newsletter.languages);
39
+ setAvailableLanguages(langs);
40
+ }
41
+ // For welcome emails, also update available languages
42
+ if (isWelcomeEmail && newsletter.languages && Object.keys(newsletter.languages).length > 0) {
43
+ const langs = Object.keys(newsletter.languages);
44
+ setAvailableLanguages(langs);
34
45
  }
35
46
  setTimeout(() => {
36
47
  dispatch({ type: 'MARK_CLEAN' });
@@ -75,8 +86,17 @@ export function CanvasEditorView({ newsletterId, darkMode, backgroundColors: pro
75
86
  }
76
87
  setCurrentLanguage(newLanguage);
77
88
  // Reload with new language
78
- const response = await fetch(`/api/plugin-newsletter/welcome-email?language=${newLanguage}`);
79
- if (response.ok) {
89
+ let response;
90
+ if (isWelcomeEmail) {
91
+ response = await fetch(`/api/plugin-newsletter/welcome-email?language=${newLanguage}`);
92
+ }
93
+ else if (newsletterId) {
94
+ response = await fetch(`/api/plugin-newsletter/newsletters/${newsletterId}?language=${newLanguage}`);
95
+ }
96
+ else {
97
+ return;
98
+ }
99
+ if (response && response.ok) {
80
100
  const newsletter = await response.json();
81
101
  helpers.loadNewsletter(newsletter);
82
102
  dispatch({ type: 'MARK_CLEAN' });
@@ -170,7 +190,8 @@ export function CanvasEditorView({ newsletterId, darkMode, backgroundColors: pro
170
190
  setIsSaving(true);
171
191
  setSaveError(null);
172
192
  try {
173
- await helpers.save(isWelcomeEmail ? { language: currentLanguage } : undefined);
193
+ // Always pass language for saving (both welcome email and regular newsletters)
194
+ await helpers.save({ language: currentLanguage });
174
195
  setIsSaving(false);
175
196
  }
176
197
  catch (error) {
@@ -7,13 +7,12 @@ export function useNewsletterLoader(newsletterId, currentNewsletterId, loadNewsl
7
7
  if (hasLoadedRef.current) {
8
8
  return;
9
9
  }
10
- // For welcome emails, wait until language is provided
11
- if (isWelcomeEmail && !language) {
10
+ // Wait until language is provided (for both welcome emails and regular newsletters)
11
+ if (!language) {
12
12
  return;
13
13
  }
14
14
  // Skip if we have a regular newsletter id but no id yet, or if this is welcome email mode
15
15
  if (isWelcomeEmail) {
16
- // Load welcome email with language
17
16
  // Load welcome email with language
18
17
  const loadWelcomeEmail = async () => {
19
18
  try {
@@ -41,7 +40,8 @@ export function useNewsletterLoader(newsletterId, currentNewsletterId, loadNewsl
41
40
  const loadNewsletterData = async () => {
42
41
  try {
43
42
  setIsLoadingNewsletter(true);
44
- const response = await fetch(`/api/plugin-newsletter/newsletters/${newsletterId}`);
43
+ const langParam = language ? `?language=${language}` : '';
44
+ const response = await fetch(`/api/plugin-newsletter/newsletters/${newsletterId}${langParam}`);
45
45
  if (!response.ok) {
46
46
  throw new Error('Failed to load newsletter');
47
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"NewsletterManager.d.ts","sourceRoot":"","sources":["../../src/views/NewsletterManager.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,MAAM,WAAW,0BAA0B;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAiBD,wBAAgB,qBAAqB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,0BAA0B,2CAgcnF"}
1
+ {"version":3,"file":"NewsletterManager.d.ts","sourceRoot":"","sources":["../../src/views/NewsletterManager.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,MAAM,WAAW,0BAA0B;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAiBD,wBAAgB,qBAAqB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,0BAA0B,2CAqnBnF"}