@headless-lms/adapter-email-templates 0.1.0 โ 0.2.1
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/dist/index.js +953 -26
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import { render } from "@react-email/render";
|
|
2
|
-
import { Body, Button, Container, Head, Heading, Hr, Html, Img, Link, Section, Tailwind, Text } from "@react-email/components";
|
|
2
|
+
import { Body, Button, Column, Container, Head, Heading, Hr, Html, Img, Link, Row, Section, Tailwind, Text } from "@react-email/components";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
//#region src/emails/layout.tsx
|
|
5
|
+
const LOGO_URL = "https://headless-lms.dev/logo.png";
|
|
6
|
+
const ICON_URL = "https://headless-lms.dev/apple-icon";
|
|
5
7
|
function Layout({ ctx, heading, children }) {
|
|
6
8
|
return /* @__PURE__ */ jsx(Html, { children: /* @__PURE__ */ jsxs(Tailwind, { children: [/* @__PURE__ */ jsx(Head, {}), /* @__PURE__ */ jsx(Body, {
|
|
7
9
|
className: "bg-white font-sans",
|
|
8
10
|
children: /* @__PURE__ */ jsxs(Container, {
|
|
9
11
|
className: "mx-auto max-w-[560px] px-6 pt-5 pb-12",
|
|
10
12
|
children: [
|
|
11
|
-
|
|
12
|
-
src:
|
|
13
|
+
/* @__PURE__ */ jsx(Img, {
|
|
14
|
+
src: LOGO_URL,
|
|
13
15
|
alt: ctx.brandName,
|
|
14
|
-
height:
|
|
15
|
-
className: "h-[
|
|
16
|
-
}) : /* @__PURE__ */ jsx(Text, {
|
|
17
|
-
className: "m-0 text-[15px] font-semibold text-[#3c4149]",
|
|
18
|
-
children: ctx.brandName
|
|
16
|
+
height: 32,
|
|
17
|
+
className: "h-[32px]"
|
|
19
18
|
}),
|
|
20
19
|
/* @__PURE__ */ jsx(Heading, {
|
|
21
20
|
className: "mt-[28px] mb-0 text-[24px] font-normal leading-[1.3] tracking-[-0.5px] text-[#484848]",
|
|
@@ -23,11 +22,23 @@ function Layout({ ctx, heading, children }) {
|
|
|
23
22
|
}),
|
|
24
23
|
/* @__PURE__ */ jsx(Section, { children }),
|
|
25
24
|
/* @__PURE__ */ jsx(Hr, { className: "mt-[42px] mb-[26px] border-[#dfe1e4]" }),
|
|
26
|
-
/* @__PURE__ */ jsx(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
/* @__PURE__ */ jsxs(Row, { children: [/* @__PURE__ */ jsx(Column, {
|
|
26
|
+
className: "w-[24px]",
|
|
27
|
+
children: /* @__PURE__ */ jsx(Img, {
|
|
28
|
+
src: ICON_URL,
|
|
29
|
+
alt: "",
|
|
30
|
+
width: 24,
|
|
31
|
+
height: 24,
|
|
32
|
+
className: "rounded-[6px]"
|
|
33
|
+
})
|
|
34
|
+
}), /* @__PURE__ */ jsx(Column, {
|
|
35
|
+
className: "pl-[8px]",
|
|
36
|
+
children: /* @__PURE__ */ jsx(Link, {
|
|
37
|
+
href: ctx.baseUrl,
|
|
38
|
+
className: "text-[14px] text-[#b4becc]",
|
|
39
|
+
children: ctx.brandName
|
|
40
|
+
})
|
|
41
|
+
})] })
|
|
31
42
|
]
|
|
32
43
|
})
|
|
33
44
|
})] }) });
|
|
@@ -55,7 +66,7 @@ const PREVIEW_CTX = {
|
|
|
55
66
|
};
|
|
56
67
|
//#endregion
|
|
57
68
|
//#region src/emails/magic-link.tsx
|
|
58
|
-
const subject$
|
|
69
|
+
const subject$8 = (ctx, _params) => `Sign in to ${ctx.brandName}`;
|
|
59
70
|
function MagicLink({ ctx, params }) {
|
|
60
71
|
return /* @__PURE__ */ jsxs(Layout, {
|
|
61
72
|
ctx,
|
|
@@ -76,7 +87,7 @@ MagicLink.PreviewProps = {
|
|
|
76
87
|
};
|
|
77
88
|
//#endregion
|
|
78
89
|
//#region src/emails/student-invite.tsx
|
|
79
|
-
const subject$
|
|
90
|
+
const subject$7 = (ctx, _params) => `You're invited to ${ctx.brandName}`;
|
|
80
91
|
function StudentInvite({ ctx, params }) {
|
|
81
92
|
return /* @__PURE__ */ jsxs(Layout, {
|
|
82
93
|
ctx,
|
|
@@ -105,7 +116,7 @@ StudentInvite.PreviewProps = {
|
|
|
105
116
|
};
|
|
106
117
|
//#endregion
|
|
107
118
|
//#region src/emails/member-invite.tsx
|
|
108
|
-
const subject$
|
|
119
|
+
const subject$6 = (ctx, _params) => `You've been invited to join ${ctx.brandName}`;
|
|
109
120
|
function MemberInvite({ ctx, params }) {
|
|
110
121
|
return /* @__PURE__ */ jsxs(Layout, {
|
|
111
122
|
ctx,
|
|
@@ -132,12 +143,12 @@ MemberInvite.PreviewProps = {
|
|
|
132
143
|
params: {
|
|
133
144
|
inviteUrl: "http://localhost:8001/invite?token=demo",
|
|
134
145
|
inviterName: "Ann",
|
|
135
|
-
role: "
|
|
146
|
+
role: "Admin"
|
|
136
147
|
}
|
|
137
148
|
};
|
|
138
149
|
//#endregion
|
|
139
150
|
//#region src/emails/password-reset.tsx
|
|
140
|
-
const subject$
|
|
151
|
+
const subject$5 = (ctx, _params) => `Reset your ${ctx.brandName} password`;
|
|
141
152
|
function PasswordReset({ ctx, params }) {
|
|
142
153
|
return /* @__PURE__ */ jsxs(Layout, {
|
|
143
154
|
ctx,
|
|
@@ -157,6 +168,24 @@ PasswordReset.PreviewProps = {
|
|
|
157
168
|
params: { resetUrl: "http://localhost:8002/reset?token=demo" }
|
|
158
169
|
};
|
|
159
170
|
//#endregion
|
|
171
|
+
//#region src/emails/password-changed.tsx
|
|
172
|
+
const subject$4 = (ctx, _params) => `Your ${ctx.brandName} password was changed`;
|
|
173
|
+
function PasswordChanged({ ctx }) {
|
|
174
|
+
return /* @__PURE__ */ jsxs(Layout, {
|
|
175
|
+
ctx,
|
|
176
|
+
heading: "Your password was changed",
|
|
177
|
+
children: [/* @__PURE__ */ jsxs(Paragraph, { children: [
|
|
178
|
+
"The password for your ",
|
|
179
|
+
ctx.brandName,
|
|
180
|
+
" account was just changed."
|
|
181
|
+
] }), /* @__PURE__ */ jsx(Paragraph, { children: "If you didn't make this change, reply to this email right away." })]
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
PasswordChanged.PreviewProps = {
|
|
185
|
+
ctx: PREVIEW_CTX,
|
|
186
|
+
params: {}
|
|
187
|
+
};
|
|
188
|
+
//#endregion
|
|
160
189
|
//#region src/emails/email-verification.tsx
|
|
161
190
|
const subject$3 = (ctx, _params) => `Verify your email for ${ctx.brandName}`;
|
|
162
191
|
function EmailVerification({ ctx, params }) {
|
|
@@ -176,13 +205,29 @@ EmailVerification.PreviewProps = {
|
|
|
176
205
|
//#endregion
|
|
177
206
|
//#region src/emails/access-granted.tsx
|
|
178
207
|
const subject$2 = (_ctx, params) => `You now have access to ${params.contentTitle}`;
|
|
208
|
+
const PORTAL_PATH = {
|
|
209
|
+
course: "courses",
|
|
210
|
+
download: "downloads",
|
|
211
|
+
community: "communities",
|
|
212
|
+
event: "events"
|
|
213
|
+
};
|
|
214
|
+
const BUTTON = {
|
|
215
|
+
course: "Start learning",
|
|
216
|
+
download: "View download",
|
|
217
|
+
community: "Open community",
|
|
218
|
+
event: "Open event",
|
|
219
|
+
bundle: "Open your library"
|
|
220
|
+
};
|
|
221
|
+
function hrefOf(ctx, params) {
|
|
222
|
+
return params.contentType === "bundle" ? ctx.studentPortalUrl : `${ctx.studentPortalUrl}/${PORTAL_PATH[params.contentType]}/${params.contentId}`;
|
|
223
|
+
}
|
|
179
224
|
function AccessGranted({ ctx, params }) {
|
|
180
225
|
return /* @__PURE__ */ jsxs(Layout, {
|
|
181
226
|
ctx,
|
|
182
227
|
heading: `${params.contentTitle} is ready for you`,
|
|
183
|
-
children: [/* @__PURE__ */ jsx(Paragraph, { children: "You've been granted access. Jump in whenever you're ready." }), /* @__PURE__ */ jsx(EmailButton, {
|
|
184
|
-
href:
|
|
185
|
-
children:
|
|
228
|
+
children: [/* @__PURE__ */ jsx(Paragraph, { children: params.contentType === "bundle" ? "You've been granted access to everything it includes. Jump in whenever you're ready." : "You've been granted access. Jump in whenever you're ready." }), /* @__PURE__ */ jsx(EmailButton, {
|
|
229
|
+
href: hrefOf(ctx, params),
|
|
230
|
+
children: BUTTON[params.contentType]
|
|
186
231
|
})]
|
|
187
232
|
});
|
|
188
233
|
}
|
|
@@ -190,7 +235,8 @@ AccessGranted.PreviewProps = {
|
|
|
190
235
|
ctx: PREVIEW_CTX,
|
|
191
236
|
params: {
|
|
192
237
|
contentTitle: "Fly Tying 101",
|
|
193
|
-
contentId: "demo"
|
|
238
|
+
contentId: "demo",
|
|
239
|
+
contentType: "course"
|
|
194
240
|
}
|
|
195
241
|
};
|
|
196
242
|
//#endregion
|
|
@@ -230,24 +276,761 @@ CourseCompleted.PreviewProps = {
|
|
|
230
276
|
params: { courseTitle: "Fly Tying 101" }
|
|
231
277
|
};
|
|
232
278
|
//#endregion
|
|
279
|
+
//#region src/emails/community.tsx
|
|
280
|
+
function portal(ctx, path) {
|
|
281
|
+
return `${ctx.studentPortalUrl}${path}`;
|
|
282
|
+
}
|
|
283
|
+
function defineEmail(opts) {
|
|
284
|
+
function Component({ ctx, params }) {
|
|
285
|
+
const button = opts.button?.(ctx, params);
|
|
286
|
+
return /* @__PURE__ */ jsxs(Layout, {
|
|
287
|
+
ctx,
|
|
288
|
+
heading: opts.heading(params),
|
|
289
|
+
children: [opts.lines(params).map((line, index) => /* @__PURE__ */ jsx(Paragraph, { children: line }, index)), button ? /* @__PURE__ */ jsx(EmailButton, {
|
|
290
|
+
href: button.href,
|
|
291
|
+
children: button.label
|
|
292
|
+
}) : null]
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
Component.PreviewProps = {
|
|
296
|
+
ctx: PREVIEW_CTX,
|
|
297
|
+
params: opts.preview
|
|
298
|
+
};
|
|
299
|
+
return {
|
|
300
|
+
subject: opts.subject,
|
|
301
|
+
Component
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
const community = (ctx, id) => portal(ctx, `/communities/${id}`);
|
|
305
|
+
const space = (ctx, communityId, spaceId) => portal(ctx, `/communities/${communityId}/spaces/${spaceId}`);
|
|
306
|
+
const post = (ctx, communityId, postId) => portal(ctx, `/communities/${communityId}/posts/${postId}`);
|
|
307
|
+
const comment = (ctx, communityId, postId, commentId) => `${post(ctx, communityId, postId)}#${commentId}`;
|
|
308
|
+
const chat = (ctx, communityId, chatId) => portal(ctx, `/communities/${communityId}/chats/${chatId}`);
|
|
309
|
+
function accessEnds(value) {
|
|
310
|
+
const date = new Date(value);
|
|
311
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
312
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
313
|
+
day: "numeric",
|
|
314
|
+
month: "long",
|
|
315
|
+
year: "numeric",
|
|
316
|
+
timeZone: "UTC"
|
|
317
|
+
}).format(date);
|
|
318
|
+
}
|
|
319
|
+
const welcomeToCommunity = defineEmail({
|
|
320
|
+
subject: (_ctx, params) => `Welcome to ${params.communityTitle}`,
|
|
321
|
+
heading: (params) => params.communityTitle,
|
|
322
|
+
lines: (params) => [params.spaceNames.length > 0 ? `You can open ${params.spaceNames.join(", ")}.` : "You're a member."],
|
|
323
|
+
button: (ctx, params) => ({
|
|
324
|
+
href: community(ctx, params.communityId),
|
|
325
|
+
label: "Open community"
|
|
326
|
+
}),
|
|
327
|
+
preview: {
|
|
328
|
+
communityTitle: "Founders",
|
|
329
|
+
communityId: "cmy_1",
|
|
330
|
+
spaceNames: ["Announcements"]
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
const membershipEndingSoon = defineEmail({
|
|
334
|
+
subject: (_ctx, params) => `${params.communityTitle} ends soon`,
|
|
335
|
+
heading: (params) => `${params.communityTitle} ends soon`,
|
|
336
|
+
lines: (params) => [`Your access ends ${accessEnds(params.expiresAt)}.`],
|
|
337
|
+
button: (ctx, params) => ({
|
|
338
|
+
href: community(ctx, params.communityId),
|
|
339
|
+
label: "Renew"
|
|
340
|
+
}),
|
|
341
|
+
preview: {
|
|
342
|
+
communityTitle: "Founders",
|
|
343
|
+
communityId: "cmy_1",
|
|
344
|
+
expiresAt: "2026-10-28T00:00:00.000Z"
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
function communityTitles(params) {
|
|
348
|
+
return params.communities.map((item) => item.communityTitle).join(", ");
|
|
349
|
+
}
|
|
350
|
+
const membershipEnded = defineEmail({
|
|
351
|
+
subject: (_ctx, params) => `${communityTitles(params)} has ended`,
|
|
352
|
+
heading: (params) => `${communityTitles(params)} has ended`,
|
|
353
|
+
lines: (params) => [params.communities.length === 1 ? "Your access to this community has ended." : "Your access to these communities has ended."],
|
|
354
|
+
button: (ctx, params) => {
|
|
355
|
+
const [only] = params.communities;
|
|
356
|
+
return params.communities.length === 1 && only ? {
|
|
357
|
+
href: community(ctx, only.communityId),
|
|
358
|
+
label: "Renew"
|
|
359
|
+
} : {
|
|
360
|
+
href: portal(ctx, "/communities"),
|
|
361
|
+
label: "Open communities"
|
|
362
|
+
};
|
|
363
|
+
},
|
|
364
|
+
preview: { communities: [{
|
|
365
|
+
communityId: "cmy_1",
|
|
366
|
+
communityTitle: "Founders"
|
|
367
|
+
}] }
|
|
368
|
+
});
|
|
369
|
+
const newPostInSpace = defineEmail({
|
|
370
|
+
subject: (_ctx, params) => `${params.authorName} posted in ${params.spaceName}`,
|
|
371
|
+
heading: (params) => params.postTitle,
|
|
372
|
+
lines: (params) => [`${params.authorName} in ${params.spaceName}`, params.excerpt],
|
|
373
|
+
button: (ctx, params) => ({
|
|
374
|
+
href: post(ctx, params.communityId, params.postId),
|
|
375
|
+
label: "Read post"
|
|
376
|
+
}),
|
|
377
|
+
preview: {
|
|
378
|
+
spaceName: "Announcements",
|
|
379
|
+
postTitle: "Hello",
|
|
380
|
+
authorName: "Ann",
|
|
381
|
+
excerpt: "A short note",
|
|
382
|
+
postId: "pst_1",
|
|
383
|
+
communityId: "cmy_1"
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
const yourPostWasPublished = defineEmail({
|
|
387
|
+
subject: (_ctx, params) => `Your post was published in ${params.spaceName}`,
|
|
388
|
+
heading: (params) => params.postTitle,
|
|
389
|
+
lines: (params) => [`It's live in ${params.spaceName}.`],
|
|
390
|
+
button: (ctx, params) => ({
|
|
391
|
+
href: post(ctx, params.communityId, params.postId),
|
|
392
|
+
label: "View post"
|
|
393
|
+
}),
|
|
394
|
+
preview: {
|
|
395
|
+
postTitle: "Hello",
|
|
396
|
+
spaceName: "Announcements",
|
|
397
|
+
postId: "pst_1",
|
|
398
|
+
communityId: "cmy_1"
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
const yourPostWasRemoved = defineEmail({
|
|
402
|
+
subject: (_ctx, params) => `Your post was removed from ${params.spaceName}`,
|
|
403
|
+
heading: (params) => params.postTitle,
|
|
404
|
+
lines: (params) => [`It was removed from ${params.spaceName}.`],
|
|
405
|
+
button: (ctx, params) => ({
|
|
406
|
+
href: space(ctx, params.communityId, params.spaceId),
|
|
407
|
+
label: "Open space"
|
|
408
|
+
}),
|
|
409
|
+
preview: {
|
|
410
|
+
postTitle: "Hello",
|
|
411
|
+
spaceName: "Announcements",
|
|
412
|
+
spaceId: "spc_1",
|
|
413
|
+
communityId: "cmy_1"
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
const newCommentOnPost = defineEmail({
|
|
417
|
+
subject: (_ctx, params) => `${params.commenterName} commented on ${params.postTitle}`,
|
|
418
|
+
heading: (params) => params.postTitle,
|
|
419
|
+
lines: (params) => [params.commenterName, params.excerpt],
|
|
420
|
+
button: (ctx, params) => ({
|
|
421
|
+
href: comment(ctx, params.communityId, params.postId, params.commentId),
|
|
422
|
+
label: "View comment"
|
|
423
|
+
}),
|
|
424
|
+
preview: {
|
|
425
|
+
postTitle: "Hello",
|
|
426
|
+
commenterName: "Sam",
|
|
427
|
+
excerpt: "Nice",
|
|
428
|
+
commentId: "cmt_1",
|
|
429
|
+
postId: "pst_1",
|
|
430
|
+
communityId: "cmy_1"
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
const replyToYourComment = defineEmail({
|
|
434
|
+
subject: (_ctx, params) => `${params.commenterName} replied on ${params.postTitle}`,
|
|
435
|
+
heading: (params) => params.postTitle,
|
|
436
|
+
lines: (params) => [params.commenterName, params.excerpt],
|
|
437
|
+
button: (ctx, params) => ({
|
|
438
|
+
href: comment(ctx, params.communityId, params.postId, params.commentId),
|
|
439
|
+
label: "View reply"
|
|
440
|
+
}),
|
|
441
|
+
preview: {
|
|
442
|
+
postTitle: "Hello",
|
|
443
|
+
commenterName: "Sam",
|
|
444
|
+
excerpt: "Thanks",
|
|
445
|
+
commentId: "cmt_2",
|
|
446
|
+
postId: "pst_1",
|
|
447
|
+
communityId: "cmy_1"
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
const yourCommentWasRemoved = defineEmail({
|
|
451
|
+
subject: (_ctx, params) => `Your comment was removed from ${params.postTitle}`,
|
|
452
|
+
heading: (params) => params.postTitle,
|
|
453
|
+
lines: () => ["Your comment was removed."],
|
|
454
|
+
button: (ctx, params) => ({
|
|
455
|
+
href: post(ctx, params.communityId, params.postId),
|
|
456
|
+
label: "View post"
|
|
457
|
+
}),
|
|
458
|
+
preview: {
|
|
459
|
+
postTitle: "Hello",
|
|
460
|
+
postId: "pst_1",
|
|
461
|
+
communityId: "cmy_1"
|
|
462
|
+
}
|
|
463
|
+
});
|
|
464
|
+
const requestApproved = defineEmail({
|
|
465
|
+
subject: (_ctx, params) => `You're in ${params.spaceName}`,
|
|
466
|
+
heading: (params) => params.spaceName,
|
|
467
|
+
lines: (params) => [`Your request to join ${params.spaceName} was approved.`],
|
|
468
|
+
button: (ctx, params) => ({
|
|
469
|
+
href: space(ctx, params.communityId, params.spaceId),
|
|
470
|
+
label: "Open space"
|
|
471
|
+
}),
|
|
472
|
+
preview: {
|
|
473
|
+
spaceName: "SaaS",
|
|
474
|
+
spaceId: "spc_1",
|
|
475
|
+
communityId: "cmy_1"
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
const requestDeclined = defineEmail({
|
|
479
|
+
subject: (_ctx, params) => `Request declined for ${params.spaceName}`,
|
|
480
|
+
heading: (params) => params.spaceName,
|
|
481
|
+
lines: (params) => [`Your request to join ${params.spaceName} was declined.`],
|
|
482
|
+
button: (ctx, params) => ({
|
|
483
|
+
href: community(ctx, params.communityId),
|
|
484
|
+
label: "Open community"
|
|
485
|
+
}),
|
|
486
|
+
preview: {
|
|
487
|
+
spaceName: "SaaS",
|
|
488
|
+
communityId: "cmy_1"
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
const invitedToSpace = defineEmail({
|
|
492
|
+
subject: (_ctx, params) => `${params.inviterName} invited you to ${params.spaceName}`,
|
|
493
|
+
heading: (params) => params.spaceName,
|
|
494
|
+
lines: (params) => [`${params.inviterName} invited you.`],
|
|
495
|
+
button: (ctx, params) => ({
|
|
496
|
+
href: space(ctx, params.communityId, params.spaceId),
|
|
497
|
+
label: "Accept"
|
|
498
|
+
}),
|
|
499
|
+
preview: {
|
|
500
|
+
spaceName: "SaaS",
|
|
501
|
+
inviterName: "Ann",
|
|
502
|
+
spaceId: "spc_1",
|
|
503
|
+
communityId: "cmy_1"
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
const messageRequest = defineEmail({
|
|
507
|
+
subject: (_ctx, params) => `${params.senderName} sent a message request`,
|
|
508
|
+
heading: (params) => params.senderName,
|
|
509
|
+
lines: (params) => [params.excerpt],
|
|
510
|
+
button: (ctx, params) => ({
|
|
511
|
+
href: chat(ctx, params.communityId, params.chatId),
|
|
512
|
+
label: "View request"
|
|
513
|
+
}),
|
|
514
|
+
preview: {
|
|
515
|
+
senderName: "Ann",
|
|
516
|
+
excerpt: "Hello",
|
|
517
|
+
chatId: "cht_1",
|
|
518
|
+
communityId: "cmy_1"
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
const newMessage = defineEmail({
|
|
522
|
+
subject: (_ctx, params) => `${params.senderName} in ${params.chatTitle}`,
|
|
523
|
+
heading: (params) => params.chatTitle,
|
|
524
|
+
lines: (params) => [`${params.senderName}: ${params.excerpt}`],
|
|
525
|
+
button: (ctx, params) => ({
|
|
526
|
+
href: chat(ctx, params.communityId, params.chatId),
|
|
527
|
+
label: "Open chat"
|
|
528
|
+
}),
|
|
529
|
+
preview: {
|
|
530
|
+
senderName: "Ann",
|
|
531
|
+
chatTitle: "Group chat",
|
|
532
|
+
excerpt: "Hello",
|
|
533
|
+
chatId: "cht_1",
|
|
534
|
+
communityId: "cmy_1"
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
const addedToGroupChat = defineEmail({
|
|
538
|
+
subject: (_ctx, params) => `${params.adderName} added you to a chat`,
|
|
539
|
+
heading: () => "You were added to a chat",
|
|
540
|
+
lines: (params) => [`${params.adderName} added you.`, params.participantNames.join(", ")],
|
|
541
|
+
button: (ctx, params) => ({
|
|
542
|
+
href: chat(ctx, params.communityId, params.chatId),
|
|
543
|
+
label: "Open chat"
|
|
544
|
+
}),
|
|
545
|
+
preview: {
|
|
546
|
+
adderName: "Ann",
|
|
547
|
+
participantNames: ["Ann", "Sam"],
|
|
548
|
+
chatId: "cht_1",
|
|
549
|
+
communityId: "cmy_1"
|
|
550
|
+
}
|
|
551
|
+
});
|
|
552
|
+
const ROLE_PATH = {
|
|
553
|
+
course: "courses",
|
|
554
|
+
download: "downloads",
|
|
555
|
+
community: "communities",
|
|
556
|
+
event: "events"
|
|
557
|
+
};
|
|
558
|
+
const roleAssigned = defineEmail({
|
|
559
|
+
subject: (_ctx, params) => `You are now ${params.roleName} ${params.place}`,
|
|
560
|
+
heading: (params) => `You are now ${params.roleName}`,
|
|
561
|
+
lines: (params) => [`You are now ${params.roleName} ${params.place}.`],
|
|
562
|
+
button: (ctx, params) => params.contentId !== null && params.contentType !== null ? {
|
|
563
|
+
href: `${ctx.baseUrl}/${ROLE_PATH[params.contentType] ?? ""}/${params.contentId}`,
|
|
564
|
+
label: "Open"
|
|
565
|
+
} : {
|
|
566
|
+
href: ctx.baseUrl,
|
|
567
|
+
label: "Open"
|
|
568
|
+
},
|
|
569
|
+
preview: {
|
|
570
|
+
roleName: "Moderator",
|
|
571
|
+
place: "of Founders",
|
|
572
|
+
contentId: "cmy_1",
|
|
573
|
+
contentType: "community"
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
function commentsLabel(count) {
|
|
577
|
+
return count === 1 ? "1 comment" : `${count} comments`;
|
|
578
|
+
}
|
|
579
|
+
function Digest({ ctx, params }) {
|
|
580
|
+
return /* @__PURE__ */ jsxs(Layout, {
|
|
581
|
+
ctx,
|
|
582
|
+
heading: `${params.communityTitle} digest`,
|
|
583
|
+
children: [
|
|
584
|
+
/* @__PURE__ */ jsx(Paragraph, { children: "Here's what you haven't seen." }),
|
|
585
|
+
params.posts.map((item) => /* @__PURE__ */ jsxs(Section, {
|
|
586
|
+
className: "my-[12px]",
|
|
587
|
+
children: [/* @__PURE__ */ jsx(Link, {
|
|
588
|
+
href: post(ctx, params.communityId, item.postId),
|
|
589
|
+
className: "text-[16px] font-semibold text-[#18181b]",
|
|
590
|
+
children: item.title
|
|
591
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
592
|
+
className: "my-[2px] text-[14px] leading-[1.4] text-[#6b7280]",
|
|
593
|
+
children: `${item.authorName} in ${item.spaceName} ยท ${commentsLabel(item.commentCount)}`
|
|
594
|
+
})]
|
|
595
|
+
}, item.postId)),
|
|
596
|
+
/* @__PURE__ */ jsx(EmailButton, {
|
|
597
|
+
href: community(ctx, params.communityId),
|
|
598
|
+
children: "Open community"
|
|
599
|
+
})
|
|
600
|
+
]
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
Digest.PreviewProps = {
|
|
604
|
+
ctx: PREVIEW_CTX,
|
|
605
|
+
params: {
|
|
606
|
+
communityTitle: "Founders",
|
|
607
|
+
communityId: "cmy_1",
|
|
608
|
+
from: "2026-10-29T07:00:00.000Z",
|
|
609
|
+
to: "2026-11-05T07:00:00.000Z",
|
|
610
|
+
posts: [{
|
|
611
|
+
postId: "pst_1",
|
|
612
|
+
title: "Welcome, everyone",
|
|
613
|
+
authorName: "Sam",
|
|
614
|
+
spaceName: "Announcements",
|
|
615
|
+
commentCount: 4
|
|
616
|
+
}]
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
const digest = {
|
|
620
|
+
subject: (_ctx, params) => `${params.communityTitle} digest`,
|
|
621
|
+
Component: Digest
|
|
622
|
+
};
|
|
623
|
+
const postAwaitingReview = defineEmail({
|
|
624
|
+
subject: (_ctx, params) => `Post awaiting review in ${params.spaceName}`,
|
|
625
|
+
heading: (params) => params.postTitle,
|
|
626
|
+
lines: (params) => [`${params.authorName} submitted a post in ${params.spaceName}.`],
|
|
627
|
+
button: (ctx, params) => ({
|
|
628
|
+
href: space(ctx, params.communityId, params.spaceId),
|
|
629
|
+
label: "Review"
|
|
630
|
+
}),
|
|
631
|
+
preview: {
|
|
632
|
+
spaceName: "Announcements",
|
|
633
|
+
postTitle: "Hello",
|
|
634
|
+
authorName: "Sam",
|
|
635
|
+
spaceId: "spc_1",
|
|
636
|
+
communityId: "cmy_1"
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
const joinRequest = defineEmail({
|
|
640
|
+
subject: (_ctx, params) => `${params.memberName} requested ${params.spaceName}`,
|
|
641
|
+
heading: (params) => params.spaceName,
|
|
642
|
+
lines: (params) => [`${params.memberName} asked to join. Seats left: ${params.seatsLeft}.`],
|
|
643
|
+
button: (ctx, params) => ({
|
|
644
|
+
href: space(ctx, params.communityId, params.spaceId),
|
|
645
|
+
label: "Review request"
|
|
646
|
+
}),
|
|
647
|
+
preview: {
|
|
648
|
+
spaceName: "SaaS",
|
|
649
|
+
memberName: "Sam",
|
|
650
|
+
seatsLeft: "3",
|
|
651
|
+
spaceId: "spc_1",
|
|
652
|
+
communityId: "cmy_1"
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
const somethingWasFlagged = defineEmail({
|
|
656
|
+
subject: (_ctx, params) => `Something was flagged in ${params.spaceName}`,
|
|
657
|
+
heading: (params) => params.spaceName,
|
|
658
|
+
lines: (params) => [params.reason, params.excerpt],
|
|
659
|
+
button: (ctx, params) => ({
|
|
660
|
+
href: space(ctx, params.communityId, params.spaceId),
|
|
661
|
+
label: "Review"
|
|
662
|
+
}),
|
|
663
|
+
preview: {
|
|
664
|
+
spaceName: "Announcements",
|
|
665
|
+
excerpt: "Hello",
|
|
666
|
+
reason: "Spam",
|
|
667
|
+
spaceId: "spc_1",
|
|
668
|
+
communityId: "cmy_1"
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
const messageWasFlagged = defineEmail({
|
|
672
|
+
subject: () => "A message was flagged",
|
|
673
|
+
heading: () => "A message was flagged",
|
|
674
|
+
lines: (params) => [params.reason],
|
|
675
|
+
button: (ctx, params) => ({
|
|
676
|
+
href: community(ctx, params.communityId),
|
|
677
|
+
label: "Review"
|
|
678
|
+
}),
|
|
679
|
+
preview: {
|
|
680
|
+
reason: "Spam",
|
|
681
|
+
communityId: "cmy_1"
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
const postReacted = defineEmail({
|
|
685
|
+
subject: (_ctx, params) => `${params.reactorName} reacted to your post`,
|
|
686
|
+
heading: (params) => params.postTitle,
|
|
687
|
+
lines: (params) => [`${params.reactorName} reacted ${params.reaction} to your post.`],
|
|
688
|
+
button: (ctx, params) => ({
|
|
689
|
+
href: post(ctx, params.communityId, params.postId),
|
|
690
|
+
label: "View post"
|
|
691
|
+
}),
|
|
692
|
+
preview: {
|
|
693
|
+
postTitle: "Hello",
|
|
694
|
+
reactorName: "Sam",
|
|
695
|
+
reaction: "๐",
|
|
696
|
+
postId: "pst_1",
|
|
697
|
+
communityId: "cmy_1"
|
|
698
|
+
}
|
|
699
|
+
});
|
|
700
|
+
const commentReacted = defineEmail({
|
|
701
|
+
subject: (_ctx, params) => `${params.reactorName} reacted to your comment`,
|
|
702
|
+
heading: (params) => params.postTitle,
|
|
703
|
+
lines: (params) => [`${params.reactorName} reacted ${params.reaction} to:`, params.excerpt],
|
|
704
|
+
button: (ctx, params) => ({
|
|
705
|
+
href: comment(ctx, params.communityId, params.postId, params.commentId),
|
|
706
|
+
label: "View comment"
|
|
707
|
+
}),
|
|
708
|
+
preview: {
|
|
709
|
+
postTitle: "Hello",
|
|
710
|
+
excerpt: "Nice",
|
|
711
|
+
reactorName: "Sam",
|
|
712
|
+
reaction: "๐",
|
|
713
|
+
commentId: "cmt_1",
|
|
714
|
+
postId: "pst_1",
|
|
715
|
+
communityId: "cmy_1"
|
|
716
|
+
}
|
|
717
|
+
});
|
|
718
|
+
function mentionedIn(params) {
|
|
719
|
+
return "postTitle" in params ? params.postTitle : params.chatTitle;
|
|
720
|
+
}
|
|
721
|
+
const mention = defineEmail({
|
|
722
|
+
subject: (_ctx, params) => `${params.authorName} mentioned you in ${mentionedIn(params)}`,
|
|
723
|
+
heading: (params) => mentionedIn(params),
|
|
724
|
+
lines: (params) => [params.authorName, params.excerpt],
|
|
725
|
+
button: (ctx, params) => "postTitle" in params ? {
|
|
726
|
+
href: params.commentId ? comment(ctx, params.communityId, params.postId, params.commentId) : post(ctx, params.communityId, params.postId),
|
|
727
|
+
label: "View"
|
|
728
|
+
} : {
|
|
729
|
+
href: chat(ctx, params.communityId, params.chatId),
|
|
730
|
+
label: "Open chat"
|
|
731
|
+
},
|
|
732
|
+
preview: {
|
|
733
|
+
authorName: "Sam",
|
|
734
|
+
excerpt: "Thanks @Ann",
|
|
735
|
+
communityId: "cmy_1",
|
|
736
|
+
postTitle: "Hello",
|
|
737
|
+
postId: "pst_1",
|
|
738
|
+
commentId: "cmt_1"
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
const messageReacted = defineEmail({
|
|
742
|
+
subject: (_ctx, params) => `${params.reactorName} reacted to your message`,
|
|
743
|
+
heading: () => "A reaction to your message",
|
|
744
|
+
lines: (params) => [`${params.reactorName} reacted ${params.reaction} to:`, params.excerpt],
|
|
745
|
+
button: (ctx, params) => ({
|
|
746
|
+
href: chat(ctx, params.communityId, params.chatId),
|
|
747
|
+
label: "Open chat"
|
|
748
|
+
}),
|
|
749
|
+
preview: {
|
|
750
|
+
excerpt: "Hello",
|
|
751
|
+
reactorName: "Sam",
|
|
752
|
+
reaction: "๐",
|
|
753
|
+
chatId: "cht_1",
|
|
754
|
+
communityId: "cmy_1"
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
//#endregion
|
|
758
|
+
//#region src/emails/course-activity.tsx
|
|
759
|
+
const activity = (ctx, courseId, activityId) => portal(ctx, `/courses/${courseId}?activity=${activityId}`);
|
|
760
|
+
const courseActivityAdded = defineEmail({
|
|
761
|
+
subject: (_ctx, params) => `New in ${params.courseTitle}: ${params.activityTitle}`,
|
|
762
|
+
heading: (params) => params.activityTitle,
|
|
763
|
+
lines: (params) => [`${params.courseTitle}, ${params.moduleTitle}`],
|
|
764
|
+
button: (ctx, params) => ({
|
|
765
|
+
href: activity(ctx, params.courseId, params.activityId),
|
|
766
|
+
label: "Open lesson"
|
|
767
|
+
}),
|
|
768
|
+
preview: {
|
|
769
|
+
courseTitle: "Fly Tying 101",
|
|
770
|
+
moduleTitle: "Basics",
|
|
771
|
+
activityTitle: "Choosing hooks",
|
|
772
|
+
courseId: "crs_1",
|
|
773
|
+
activityId: "act_1"
|
|
774
|
+
}
|
|
775
|
+
});
|
|
776
|
+
const activityCommentCreated = defineEmail({
|
|
777
|
+
subject: (_ctx, params) => `${params.commenterName} commented on ${params.activityTitle}`,
|
|
778
|
+
heading: (params) => params.activityTitle,
|
|
779
|
+
lines: (params) => [
|
|
780
|
+
params.courseTitle,
|
|
781
|
+
params.commenterName,
|
|
782
|
+
params.excerpt
|
|
783
|
+
],
|
|
784
|
+
button: (ctx, params) => ({
|
|
785
|
+
href: activity(ctx, params.courseId, params.activityId),
|
|
786
|
+
label: "View comment"
|
|
787
|
+
}),
|
|
788
|
+
preview: {
|
|
789
|
+
activityTitle: "Choosing hooks",
|
|
790
|
+
courseTitle: "Fly Tying 101",
|
|
791
|
+
commenterName: "Sam",
|
|
792
|
+
excerpt: "Nice",
|
|
793
|
+
courseId: "crs_1",
|
|
794
|
+
activityId: "act_1",
|
|
795
|
+
commentId: "cmt_1"
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
const activityCommentRemoved = defineEmail({
|
|
799
|
+
subject: (_ctx, params) => `Your comment was removed from ${params.activityTitle}`,
|
|
800
|
+
heading: (params) => params.activityTitle,
|
|
801
|
+
lines: (params) => [`Your comment in ${params.courseTitle} was removed.`],
|
|
802
|
+
button: (ctx, params) => ({
|
|
803
|
+
href: activity(ctx, params.courseId, params.activityId),
|
|
804
|
+
label: "Open lesson"
|
|
805
|
+
}),
|
|
806
|
+
preview: {
|
|
807
|
+
activityTitle: "Choosing hooks",
|
|
808
|
+
courseTitle: "Fly Tying 101",
|
|
809
|
+
courseId: "crs_1",
|
|
810
|
+
activityId: "act_1"
|
|
811
|
+
}
|
|
812
|
+
});
|
|
813
|
+
const activityCommentReacted = defineEmail({
|
|
814
|
+
subject: (_ctx, params) => `${params.reactorName} reacted to your comment`,
|
|
815
|
+
heading: (params) => params.activityTitle,
|
|
816
|
+
lines: (params) => [`${params.reactorName} reacted ${params.reaction} to:`, params.excerpt],
|
|
817
|
+
button: (ctx, params) => ({
|
|
818
|
+
href: activity(ctx, params.courseId, params.activityId),
|
|
819
|
+
label: "View comment"
|
|
820
|
+
}),
|
|
821
|
+
preview: {
|
|
822
|
+
activityTitle: "Choosing hooks",
|
|
823
|
+
courseTitle: "Fly Tying 101",
|
|
824
|
+
excerpt: "Nice",
|
|
825
|
+
reactorName: "Sam",
|
|
826
|
+
reaction: "๐",
|
|
827
|
+
courseId: "crs_1",
|
|
828
|
+
activityId: "act_1",
|
|
829
|
+
commentId: "cmt_1"
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
const activityCommentFlagged = defineEmail({
|
|
833
|
+
subject: (_ctx, params) => `A comment was flagged in ${params.activityTitle}`,
|
|
834
|
+
heading: (params) => params.activityTitle,
|
|
835
|
+
lines: (params) => [
|
|
836
|
+
params.courseTitle,
|
|
837
|
+
params.reason,
|
|
838
|
+
params.excerpt
|
|
839
|
+
],
|
|
840
|
+
button: (ctx, params) => ({
|
|
841
|
+
href: activity(ctx, params.courseId, params.activityId),
|
|
842
|
+
label: "Review"
|
|
843
|
+
}),
|
|
844
|
+
preview: {
|
|
845
|
+
activityTitle: "Choosing hooks",
|
|
846
|
+
courseTitle: "Fly Tying 101",
|
|
847
|
+
excerpt: "Hello",
|
|
848
|
+
reason: "Spam",
|
|
849
|
+
courseId: "crs_1",
|
|
850
|
+
activityId: "act_1"
|
|
851
|
+
}
|
|
852
|
+
});
|
|
853
|
+
const activityMention = defineEmail({
|
|
854
|
+
subject: (_ctx, params) => `${params.authorName} mentioned you in ${params.activityTitle}`,
|
|
855
|
+
heading: (params) => params.activityTitle,
|
|
856
|
+
lines: (params) => [
|
|
857
|
+
params.courseTitle,
|
|
858
|
+
params.authorName,
|
|
859
|
+
params.excerpt
|
|
860
|
+
],
|
|
861
|
+
button: (ctx, params) => ({
|
|
862
|
+
href: activity(ctx, params.courseId, params.activityId),
|
|
863
|
+
label: "View"
|
|
864
|
+
}),
|
|
865
|
+
preview: {
|
|
866
|
+
authorName: "Sam",
|
|
867
|
+
excerpt: "Thanks @Ann",
|
|
868
|
+
activityTitle: "Choosing hooks",
|
|
869
|
+
courseTitle: "Fly Tying 101",
|
|
870
|
+
courseId: "crs_1",
|
|
871
|
+
activityId: "act_1"
|
|
872
|
+
}
|
|
873
|
+
});
|
|
874
|
+
//#endregion
|
|
875
|
+
//#region src/emails/events.tsx
|
|
876
|
+
const PREVIEW_EVENT = {
|
|
877
|
+
eventId: "evn_1",
|
|
878
|
+
eventTitle: "Conversation practice",
|
|
879
|
+
startsAt: "2026-05-12T16:00:00.000Z",
|
|
880
|
+
endsAt: "2026-05-12T17:00:00.000Z",
|
|
881
|
+
timeZone: "Europe/London"
|
|
882
|
+
};
|
|
883
|
+
function eventPage(ctx, eventId) {
|
|
884
|
+
return portal(ctx, `/events/${eventId}`);
|
|
885
|
+
}
|
|
886
|
+
function formatIn(value, timeZone, options) {
|
|
887
|
+
const date = new Date(value);
|
|
888
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
889
|
+
try {
|
|
890
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
891
|
+
...options,
|
|
892
|
+
timeZone
|
|
893
|
+
}).format(date);
|
|
894
|
+
} catch {
|
|
895
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
896
|
+
...options,
|
|
897
|
+
timeZone: "UTC"
|
|
898
|
+
}).format(date);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
function eventWhen(params) {
|
|
902
|
+
const day = formatIn(params.startsAt, params.timeZone, {
|
|
903
|
+
weekday: "long",
|
|
904
|
+
day: "numeric",
|
|
905
|
+
month: "long",
|
|
906
|
+
year: "numeric"
|
|
907
|
+
});
|
|
908
|
+
const time = {
|
|
909
|
+
hour: "numeric",
|
|
910
|
+
minute: "2-digit"
|
|
911
|
+
};
|
|
912
|
+
return `${day}, ${formatIn(params.startsAt, params.timeZone, time)} โ ${formatIn(params.endsAt, params.timeZone, time)} (${params.timeZone})`;
|
|
913
|
+
}
|
|
914
|
+
function calendarStamp(value) {
|
|
915
|
+
return new Date(value).toISOString().replace(/[-:]/g, "").replace(/\.\d{3}/, "");
|
|
916
|
+
}
|
|
917
|
+
function googleCalendarUrl(ctx, params) {
|
|
918
|
+
return `https://calendar.google.com/calendar/render?${new URLSearchParams({
|
|
919
|
+
action: "TEMPLATE",
|
|
920
|
+
text: params.eventTitle,
|
|
921
|
+
dates: `${calendarStamp(params.startsAt)}/${calendarStamp(params.endsAt)}`,
|
|
922
|
+
details: eventPage(ctx, params.eventId),
|
|
923
|
+
ctz: params.timeZone
|
|
924
|
+
}).toString()}`;
|
|
925
|
+
}
|
|
926
|
+
function outlookCalendarUrl(ctx, params) {
|
|
927
|
+
return `https://outlook.live.com/calendar/0/action/compose?${new URLSearchParams({
|
|
928
|
+
path: "/calendar/action/compose",
|
|
929
|
+
rru: "addevent",
|
|
930
|
+
subject: params.eventTitle,
|
|
931
|
+
startdt: new Date(params.startsAt).toISOString(),
|
|
932
|
+
enddt: new Date(params.endsAt).toISOString(),
|
|
933
|
+
body: eventPage(ctx, params.eventId)
|
|
934
|
+
}).toString()}`;
|
|
935
|
+
}
|
|
936
|
+
function EventGranted({ ctx, params }) {
|
|
937
|
+
return /* @__PURE__ */ jsxs(Layout, {
|
|
938
|
+
ctx,
|
|
939
|
+
heading: `You're going to ${params.eventTitle}`,
|
|
940
|
+
children: [
|
|
941
|
+
/* @__PURE__ */ jsx(Paragraph, { children: eventWhen(params) }),
|
|
942
|
+
/* @__PURE__ */ jsx(EmailButton, {
|
|
943
|
+
href: eventPage(ctx, params.eventId),
|
|
944
|
+
children: "Open event"
|
|
945
|
+
}),
|
|
946
|
+
/* @__PURE__ */ jsx(Section, { children: /* @__PURE__ */ jsxs(Paragraph, { children: [
|
|
947
|
+
/* @__PURE__ */ jsx(Link, {
|
|
948
|
+
href: googleCalendarUrl(ctx, params),
|
|
949
|
+
children: "Add to Google Calendar"
|
|
950
|
+
}),
|
|
951
|
+
" ยท ",
|
|
952
|
+
/* @__PURE__ */ jsx(Link, {
|
|
953
|
+
href: outlookCalendarUrl(ctx, params),
|
|
954
|
+
children: "Add to Outlook"
|
|
955
|
+
})
|
|
956
|
+
] }) })
|
|
957
|
+
]
|
|
958
|
+
});
|
|
959
|
+
}
|
|
960
|
+
EventGranted.PreviewProps = {
|
|
961
|
+
ctx: PREVIEW_CTX,
|
|
962
|
+
params: PREVIEW_EVENT
|
|
963
|
+
};
|
|
964
|
+
const eventGranted = {
|
|
965
|
+
subject: (_ctx, params) => `You're going to ${params.eventTitle}`,
|
|
966
|
+
Component: EventGranted
|
|
967
|
+
};
|
|
968
|
+
const CHANGED = {
|
|
969
|
+
time: "The time has changed.",
|
|
970
|
+
location: "The location has changed. Open the event for the new details.",
|
|
971
|
+
time_and_location: "The time and the location have changed. Open the event for the new details."
|
|
972
|
+
};
|
|
973
|
+
const open = (ctx, params) => ({
|
|
974
|
+
href: eventPage(ctx, params.eventId),
|
|
975
|
+
label: "Open event"
|
|
976
|
+
});
|
|
977
|
+
const eventStartingSoon = defineEmail({
|
|
978
|
+
subject: (_ctx, params) => `${params.eventTitle} starts in ${params.leadText}`,
|
|
979
|
+
heading: (params) => `${params.eventTitle} starts in ${params.leadText}`,
|
|
980
|
+
lines: (params) => [eventWhen(params), "Open the event for the link."],
|
|
981
|
+
button: open,
|
|
982
|
+
preview: {
|
|
983
|
+
...PREVIEW_EVENT,
|
|
984
|
+
leadText: "1 hour"
|
|
985
|
+
}
|
|
986
|
+
});
|
|
987
|
+
const eventChanged = defineEmail({
|
|
988
|
+
subject: (_ctx, params) => `${params.eventTitle} has changed`,
|
|
989
|
+
heading: (params) => `${params.eventTitle} has changed`,
|
|
990
|
+
lines: (params) => [CHANGED[params.changed], eventWhen(params)],
|
|
991
|
+
button: open,
|
|
992
|
+
preview: {
|
|
993
|
+
...PREVIEW_EVENT,
|
|
994
|
+
changed: "time"
|
|
995
|
+
}
|
|
996
|
+
});
|
|
997
|
+
const eventCanceled = defineEmail({
|
|
998
|
+
subject: (_ctx, params) => `${params.eventTitle} was canceled`,
|
|
999
|
+
heading: (params) => `${params.eventTitle} was canceled`,
|
|
1000
|
+
lines: (params) => [`It was planned for ${eventWhen(params)}.`],
|
|
1001
|
+
button: open,
|
|
1002
|
+
preview: PREVIEW_EVENT
|
|
1003
|
+
});
|
|
1004
|
+
const eventRevoked = defineEmail({
|
|
1005
|
+
subject: (_ctx, params) => `You're no longer going to ${params.eventTitle}`,
|
|
1006
|
+
heading: (params) => `You're no longer going to ${params.eventTitle}`,
|
|
1007
|
+
lines: (params) => [`You've been removed from the event on ${eventWhen(params)}.`],
|
|
1008
|
+
button: open,
|
|
1009
|
+
preview: PREVIEW_EVENT
|
|
1010
|
+
});
|
|
1011
|
+
//#endregion
|
|
233
1012
|
//#region src/index.tsx
|
|
234
1013
|
const registry = {
|
|
235
1014
|
magicLink: {
|
|
236
|
-
subject: subject$
|
|
1015
|
+
subject: subject$8,
|
|
237
1016
|
Component: MagicLink
|
|
238
1017
|
},
|
|
239
1018
|
studentInvite: {
|
|
240
|
-
subject: subject$
|
|
1019
|
+
subject: subject$7,
|
|
241
1020
|
Component: StudentInvite
|
|
242
1021
|
},
|
|
243
1022
|
memberInvite: {
|
|
244
|
-
subject: subject$
|
|
1023
|
+
subject: subject$6,
|
|
245
1024
|
Component: MemberInvite
|
|
246
1025
|
},
|
|
247
1026
|
passwordReset: {
|
|
248
|
-
subject: subject$
|
|
1027
|
+
subject: subject$5,
|
|
249
1028
|
Component: PasswordReset
|
|
250
1029
|
},
|
|
1030
|
+
passwordChanged: {
|
|
1031
|
+
subject: subject$4,
|
|
1032
|
+
Component: PasswordChanged
|
|
1033
|
+
},
|
|
251
1034
|
emailVerification: {
|
|
252
1035
|
subject: subject$3,
|
|
253
1036
|
Component: EmailVerification
|
|
@@ -263,6 +1046,150 @@ const registry = {
|
|
|
263
1046
|
courseCompleted: {
|
|
264
1047
|
subject,
|
|
265
1048
|
Component: CourseCompleted
|
|
1049
|
+
},
|
|
1050
|
+
welcomeToCommunity: {
|
|
1051
|
+
subject: welcomeToCommunity.subject,
|
|
1052
|
+
Component: welcomeToCommunity.Component
|
|
1053
|
+
},
|
|
1054
|
+
membershipEndingSoon: {
|
|
1055
|
+
subject: membershipEndingSoon.subject,
|
|
1056
|
+
Component: membershipEndingSoon.Component
|
|
1057
|
+
},
|
|
1058
|
+
membershipEnded: {
|
|
1059
|
+
subject: membershipEnded.subject,
|
|
1060
|
+
Component: membershipEnded.Component
|
|
1061
|
+
},
|
|
1062
|
+
newPostInSpace: {
|
|
1063
|
+
subject: newPostInSpace.subject,
|
|
1064
|
+
Component: newPostInSpace.Component
|
|
1065
|
+
},
|
|
1066
|
+
yourPostWasPublished: {
|
|
1067
|
+
subject: yourPostWasPublished.subject,
|
|
1068
|
+
Component: yourPostWasPublished.Component
|
|
1069
|
+
},
|
|
1070
|
+
yourPostWasRemoved: {
|
|
1071
|
+
subject: yourPostWasRemoved.subject,
|
|
1072
|
+
Component: yourPostWasRemoved.Component
|
|
1073
|
+
},
|
|
1074
|
+
newCommentOnPost: {
|
|
1075
|
+
subject: newCommentOnPost.subject,
|
|
1076
|
+
Component: newCommentOnPost.Component
|
|
1077
|
+
},
|
|
1078
|
+
replyToYourComment: {
|
|
1079
|
+
subject: replyToYourComment.subject,
|
|
1080
|
+
Component: replyToYourComment.Component
|
|
1081
|
+
},
|
|
1082
|
+
yourCommentWasRemoved: {
|
|
1083
|
+
subject: yourCommentWasRemoved.subject,
|
|
1084
|
+
Component: yourCommentWasRemoved.Component
|
|
1085
|
+
},
|
|
1086
|
+
requestApproved: {
|
|
1087
|
+
subject: requestApproved.subject,
|
|
1088
|
+
Component: requestApproved.Component
|
|
1089
|
+
},
|
|
1090
|
+
requestDeclined: {
|
|
1091
|
+
subject: requestDeclined.subject,
|
|
1092
|
+
Component: requestDeclined.Component
|
|
1093
|
+
},
|
|
1094
|
+
invitedToSpace: {
|
|
1095
|
+
subject: invitedToSpace.subject,
|
|
1096
|
+
Component: invitedToSpace.Component
|
|
1097
|
+
},
|
|
1098
|
+
messageRequest: {
|
|
1099
|
+
subject: messageRequest.subject,
|
|
1100
|
+
Component: messageRequest.Component
|
|
1101
|
+
},
|
|
1102
|
+
newMessage: {
|
|
1103
|
+
subject: newMessage.subject,
|
|
1104
|
+
Component: newMessage.Component
|
|
1105
|
+
},
|
|
1106
|
+
addedToGroupChat: {
|
|
1107
|
+
subject: addedToGroupChat.subject,
|
|
1108
|
+
Component: addedToGroupChat.Component
|
|
1109
|
+
},
|
|
1110
|
+
roleAssigned: {
|
|
1111
|
+
subject: roleAssigned.subject,
|
|
1112
|
+
Component: roleAssigned.Component
|
|
1113
|
+
},
|
|
1114
|
+
digest: {
|
|
1115
|
+
subject: digest.subject,
|
|
1116
|
+
Component: digest.Component
|
|
1117
|
+
},
|
|
1118
|
+
postAwaitingReview: {
|
|
1119
|
+
subject: postAwaitingReview.subject,
|
|
1120
|
+
Component: postAwaitingReview.Component
|
|
1121
|
+
},
|
|
1122
|
+
joinRequest: {
|
|
1123
|
+
subject: joinRequest.subject,
|
|
1124
|
+
Component: joinRequest.Component
|
|
1125
|
+
},
|
|
1126
|
+
somethingWasFlagged: {
|
|
1127
|
+
subject: somethingWasFlagged.subject,
|
|
1128
|
+
Component: somethingWasFlagged.Component
|
|
1129
|
+
},
|
|
1130
|
+
messageWasFlagged: {
|
|
1131
|
+
subject: messageWasFlagged.subject,
|
|
1132
|
+
Component: messageWasFlagged.Component
|
|
1133
|
+
},
|
|
1134
|
+
postReacted: {
|
|
1135
|
+
subject: postReacted.subject,
|
|
1136
|
+
Component: postReacted.Component
|
|
1137
|
+
},
|
|
1138
|
+
commentReacted: {
|
|
1139
|
+
subject: commentReacted.subject,
|
|
1140
|
+
Component: commentReacted.Component
|
|
1141
|
+
},
|
|
1142
|
+
mention: {
|
|
1143
|
+
subject: mention.subject,
|
|
1144
|
+
Component: mention.Component
|
|
1145
|
+
},
|
|
1146
|
+
messageReacted: {
|
|
1147
|
+
subject: messageReacted.subject,
|
|
1148
|
+
Component: messageReacted.Component
|
|
1149
|
+
},
|
|
1150
|
+
courseActivityAdded: {
|
|
1151
|
+
subject: courseActivityAdded.subject,
|
|
1152
|
+
Component: courseActivityAdded.Component
|
|
1153
|
+
},
|
|
1154
|
+
activityCommentCreated: {
|
|
1155
|
+
subject: activityCommentCreated.subject,
|
|
1156
|
+
Component: activityCommentCreated.Component
|
|
1157
|
+
},
|
|
1158
|
+
activityCommentRemoved: {
|
|
1159
|
+
subject: activityCommentRemoved.subject,
|
|
1160
|
+
Component: activityCommentRemoved.Component
|
|
1161
|
+
},
|
|
1162
|
+
activityCommentReacted: {
|
|
1163
|
+
subject: activityCommentReacted.subject,
|
|
1164
|
+
Component: activityCommentReacted.Component
|
|
1165
|
+
},
|
|
1166
|
+
activityCommentFlagged: {
|
|
1167
|
+
subject: activityCommentFlagged.subject,
|
|
1168
|
+
Component: activityCommentFlagged.Component
|
|
1169
|
+
},
|
|
1170
|
+
activityMention: {
|
|
1171
|
+
subject: activityMention.subject,
|
|
1172
|
+
Component: activityMention.Component
|
|
1173
|
+
},
|
|
1174
|
+
eventGranted: {
|
|
1175
|
+
subject: eventGranted.subject,
|
|
1176
|
+
Component: eventGranted.Component
|
|
1177
|
+
},
|
|
1178
|
+
eventStartingSoon: {
|
|
1179
|
+
subject: eventStartingSoon.subject,
|
|
1180
|
+
Component: eventStartingSoon.Component
|
|
1181
|
+
},
|
|
1182
|
+
eventChanged: {
|
|
1183
|
+
subject: eventChanged.subject,
|
|
1184
|
+
Component: eventChanged.Component
|
|
1185
|
+
},
|
|
1186
|
+
eventCanceled: {
|
|
1187
|
+
subject: eventCanceled.subject,
|
|
1188
|
+
Component: eventCanceled.Component
|
|
1189
|
+
},
|
|
1190
|
+
eventRevoked: {
|
|
1191
|
+
subject: eventRevoked.subject,
|
|
1192
|
+
Component: eventRevoked.Component
|
|
266
1193
|
}
|
|
267
1194
|
};
|
|
268
1195
|
var ReactEmailTemplateRenderer = class {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["subject","subject","subject","subject","subject","subject","subject","magicLink","studentInvite","memberInvite","passwordReset","emailVerification","accessGranted","accessRevoked","courseCompleted"],"sources":["../src/emails/layout.tsx","../src/emails/magic-link.tsx","../src/emails/student-invite.tsx","../src/emails/member-invite.tsx","../src/emails/password-reset.tsx","../src/emails/email-verification.tsx","../src/emails/access-granted.tsx","../src/emails/access-revoked.tsx","../src/emails/course-completed.tsx","../src/index.tsx"],"sourcesContent":["import { Body, Button, Container, Head, Heading, Hr, Html, Img, Link, Section, Tailwind, Text } from '@react-email/components';\nimport type { ReactNode } from 'react';\nimport type { TemplateContext } from '@headless-lms/core/types';\n\nexport function Layout({ ctx, heading, children }: {\n ctx: TemplateContext;\n heading: string;\n children: ReactNode;\n}) {\n return (\n <Html>\n <Tailwind>\n <Head />\n <Body className=\"bg-white font-sans\">\n <Container className=\"mx-auto max-w-[560px] px-6 pt-5 pb-12\">\n {ctx.logoUrl ? (\n <Img src={ctx.logoUrl} alt={ctx.brandName} height={42} className=\"h-[42px]\" />\n ) : (\n <Text className=\"m-0 text-[15px] font-semibold text-[#3c4149]\">{ctx.brandName}</Text>\n )}\n <Heading className=\"mt-[28px] mb-0 text-[24px] font-normal leading-[1.3] tracking-[-0.5px] text-[#484848]\">\n {heading}\n </Heading>\n <Section>{children}</Section>\n <Hr className=\"mt-[42px] mb-[26px] border-[#dfe1e4]\" />\n <Link href={ctx.baseUrl} className=\"text-[14px] text-[#b4becc]\">\n {ctx.brandName}\n </Link>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n}\n\nexport function EmailButton({ href, children }: { href: string; children: ReactNode }) {\n return (\n <Section className=\"py-[20px]\">\n <Button\n href={href}\n className=\"rounded-[3px] bg-[#18181b] px-[23px] py-[11px] text-[15px] font-semibold text-white no-underline\"\n >\n {children}\n </Button>\n </Section>\n );\n}\n\nexport function Paragraph({ children }: { children: ReactNode }) {\n return <Text className=\"my-[15px] text-[15px] leading-[1.4] text-[#3c4149]\">{children}</Text>;\n}\n\nexport const PREVIEW_CTX: TemplateContext = {\n brandName: 'Acme LMS',\n baseUrl: 'http://localhost:8001',\n studentPortalUrl: 'http://localhost:8002',\n};\n","import type { EmailTemplateParams, TemplateContext } from '@headless-lms/core/types';\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from './layout.js';\n\ntype Params = EmailTemplateParams['magicLink'];\n\nexport const subject = (ctx: TemplateContext, _params: Params) => `Sign in to ${ctx.brandName}`;\n\nexport default function MagicLink({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Sign in\">\n <Paragraph>Click the button below to sign in. This link is valid once and expires shortly.</Paragraph>\n <EmailButton href={params.url}>Sign in to {ctx.brandName}</EmailButton>\n <Paragraph>If you did not request this, you can ignore this email.</Paragraph>\n </Layout>\n );\n}\n\nMagicLink.PreviewProps = { ctx: PREVIEW_CTX, params: { url: 'http://localhost:8002/magic?token=demo' } };\n","import type { EmailTemplateParams, TemplateContext } from '@headless-lms/core/types';\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from './layout.js';\n\ntype Params = EmailTemplateParams['studentInvite'];\n\nexport const subject = (ctx: TemplateContext, _params: Params) => `You're invited to ${ctx.brandName}`;\n\nexport default function StudentInvite({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Welcome\">\n <Paragraph>\n {params.studentName}, you've been invited to {ctx.brandName}. Create your account to get started.\n </Paragraph>\n <EmailButton href={params.inviteUrl}>Create your account</EmailButton>\n <Paragraph>This invitation link is personal โ please don't forward it.</Paragraph>\n </Layout>\n );\n}\n\nStudentInvite.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {\n inviteUrl: 'http://localhost:8002/welcome?token=demo',\n studentName: 'Sam',\n },\n};\n","import type { EmailTemplateParams, TemplateContext } from '@headless-lms/core/types';\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from './layout.js';\n\ntype Params = EmailTemplateParams['memberInvite'];\n\nexport const subject = (ctx: TemplateContext, _params: Params) =>\n `You've been invited to join ${ctx.brandName}`;\n\nexport default function MemberInvite({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading={`Join ${ctx.brandName}`}>\n <Paragraph>\n {params.inviterName} invited you to join {ctx.brandName} as {params.role}.\n </Paragraph>\n <EmailButton href={params.inviteUrl}>Accept invitation</EmailButton>\n <Paragraph>If you weren't expecting this invitation, you can ignore this email.</Paragraph>\n </Layout>\n );\n}\n\nMemberInvite.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {\n inviteUrl: 'http://localhost:8001/invite?token=demo',\n inviterName: 'Ann',\n role: 'admin',\n },\n};\n","import type { EmailTemplateParams, TemplateContext } from '@headless-lms/core/types';\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from './layout.js';\n\ntype Params = EmailTemplateParams['passwordReset'];\n\nexport const subject = (ctx: TemplateContext, _params: Params) => `Reset your ${ctx.brandName} password`;\n\nexport default function PasswordReset({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Reset your password\">\n <Paragraph>Click the button below to choose a new password. The link expires shortly.</Paragraph>\n <EmailButton href={params.resetUrl}>Reset password</EmailButton>\n <Paragraph>If you did not request a reset, your password is unchanged and you can ignore this email.</Paragraph>\n </Layout>\n );\n}\n\nPasswordReset.PreviewProps = { ctx: PREVIEW_CTX, params: { resetUrl: 'http://localhost:8002/reset?token=demo' } };\n","import type { EmailTemplateParams, TemplateContext } from '@headless-lms/core/types';\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from './layout.js';\n\ntype Params = EmailTemplateParams['emailVerification'];\n\nexport const subject = (ctx: TemplateContext, _params: Params) => `Verify your email for ${ctx.brandName}`;\n\nexport default function EmailVerification({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Verify your email\">\n <Paragraph>Confirm this is your email address to finish setting up your account.</Paragraph>\n <EmailButton href={params.verifyUrl}>Verify email</EmailButton>\n </Layout>\n );\n}\n\nEmailVerification.PreviewProps = { ctx: PREVIEW_CTX, params: { verifyUrl: 'http://localhost:8002/verify?token=demo' } };\n","import type { EmailTemplateParams, TemplateContext } from '@headless-lms/core/types';\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from './layout.js';\n\ntype Params = EmailTemplateParams['accessGranted'];\n\nexport const subject = (_ctx: TemplateContext, params: Params) =>\n `You now have access to ${params.contentTitle}`;\n\nexport default function AccessGranted({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading={`${params.contentTitle} is ready for you`}>\n <Paragraph>You've been granted access. Jump in whenever you're ready.</Paragraph>\n <EmailButton href={`${ctx.studentPortalUrl}/courses/${params.contentId}`}>Start learning</EmailButton>\n </Layout>\n );\n}\n\nAccessGranted.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {\n contentTitle: 'Fly Tying 101',\n contentId: 'demo',\n },\n};\n","import type { EmailTemplateParams, TemplateContext } from '@headless-lms/core/types';\nimport { Layout, Paragraph, PREVIEW_CTX } from './layout.js';\n\ntype Params = EmailTemplateParams['accessRevoked'];\n\nexport const subject = (_ctx: TemplateContext, params: Params) =>\n `Your access to ${params.contentTitle} has ended`;\n\nexport default function AccessRevoked({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Access ended\">\n <Paragraph>\n Your access to {params.contentTitle} has ended. If you think this is a mistake, reply to this email.\n </Paragraph>\n </Layout>\n );\n}\n\nAccessRevoked.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {\n contentTitle: 'Fly Tying 101',\n },\n};\n","import type { EmailTemplateParams, TemplateContext } from '@headless-lms/core/types';\nimport { Layout, Paragraph, PREVIEW_CTX } from './layout.js';\n\ntype Params = EmailTemplateParams['courseCompleted'];\n\nexport const subject = (_ctx: TemplateContext, params: Params) => `You completed ${params.courseTitle} ๐`;\n\nexport default function CourseCompleted({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Congratulations!\">\n <Paragraph>You've completed {params.courseTitle}. Nice work.</Paragraph>\n </Layout>\n );\n}\n\nCourseCompleted.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {\n courseTitle: 'Fly Tying 101',\n },\n};\n","// Default TemplateRenderer: react-email components rendered at call time.\nimport { render } from '@react-email/render';\nimport type { JSX } from 'react';\nimport type {\n EmailContent,\n EmailTemplateId,\n EmailTemplateParams,\n TemplateContext,\n TemplateRenderer,\n} from '@headless-lms/core/types';\nimport MagicLink, { subject as magicLink } from './emails/magic-link.js';\nimport StudentInvite, { subject as studentInvite } from './emails/student-invite.js';\nimport MemberInvite, { subject as memberInvite } from './emails/member-invite.js';\nimport PasswordReset, { subject as passwordReset } from './emails/password-reset.js';\nimport EmailVerification, { subject as emailVerification } from './emails/email-verification.js';\nimport AccessGranted, { subject as accessGranted } from './emails/access-granted.js';\nimport AccessRevoked, { subject as accessRevoked } from './emails/access-revoked.js';\nimport CourseCompleted, { subject as courseCompleted } from './emails/course-completed.js';\n\ninterface Entry<K extends EmailTemplateId> {\n subject: (ctx: TemplateContext, params: EmailTemplateParams[K]) => string;\n Component: (props: { ctx: TemplateContext; params: EmailTemplateParams[K] }) => JSX.Element;\n}\n\n// The catalog is closed: a missing key here is a compile error.\nconst registry: { [K in EmailTemplateId]: Entry<K> } = {\n magicLink: { subject: magicLink, Component: MagicLink },\n studentInvite: { subject: studentInvite, Component: StudentInvite },\n memberInvite: { subject: memberInvite, Component: MemberInvite },\n passwordReset: { subject: passwordReset, Component: PasswordReset },\n emailVerification: { subject: emailVerification, Component: EmailVerification },\n accessGranted: { subject: accessGranted, Component: AccessGranted },\n accessRevoked: { subject: accessRevoked, Component: AccessRevoked },\n courseCompleted: { subject: courseCompleted, Component: CourseCompleted },\n};\n\nexport class ReactEmailTemplateRenderer implements TemplateRenderer {\n async render<K extends EmailTemplateId>(\n id: K,\n ctx: TemplateContext,\n params: EmailTemplateParams[K],\n ): Promise<EmailContent> {\n const entry = registry[id] as Entry<K>;\n const element = <entry.Component ctx={ctx} params={params} />;\n const [html, text] = await Promise.all([render(element), render(element, { plainText: true })]);\n return { subject: entry.subject(ctx, params), html, text };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["subject","subject","subject","subject","subject","subject","subject","subject","magicLink","studentInvite","memberInvite","passwordReset","passwordChanged","emailVerification","accessGranted","accessRevoked","courseCompleted"],"sources":["../src/emails/layout.tsx","../src/emails/magic-link.tsx","../src/emails/student-invite.tsx","../src/emails/member-invite.tsx","../src/emails/password-reset.tsx","../src/emails/password-changed.tsx","../src/emails/email-verification.tsx","../src/emails/access-granted.tsx","../src/emails/access-revoked.tsx","../src/emails/course-completed.tsx","../src/emails/community.tsx","../src/emails/course-activity.tsx","../src/emails/events.tsx","../src/index.tsx"],"sourcesContent":["import {\n Body,\n Button,\n Column,\n Container,\n Head,\n Heading,\n Hr,\n Html,\n Img,\n Link,\n Row,\n Section,\n Tailwind,\n Text,\n} from \"@react-email/components\";\nimport type { ReactNode } from \"react\";\nimport type { TemplateContext } from \"@headless-lms/core/types\";\n\nconst LOGO_URL = \"https://headless-lms.dev/logo.png\";\nconst ICON_URL = \"https://headless-lms.dev/apple-icon\";\n\nexport function Layout({\n ctx,\n heading,\n children,\n}: {\n ctx: TemplateContext;\n heading: string;\n children: ReactNode;\n}) {\n return (\n <Html>\n <Tailwind>\n <Head />\n <Body className=\"bg-white font-sans\">\n <Container className=\"mx-auto max-w-[560px] px-6 pt-5 pb-12\">\n <Img src={LOGO_URL} alt={ctx.brandName} height={32} className=\"h-[32px]\" />\n <Heading className=\"mt-[28px] mb-0 text-[24px] font-normal leading-[1.3] tracking-[-0.5px] text-[#484848]\">\n {heading}\n </Heading>\n <Section>{children}</Section>\n <Hr className=\"mt-[42px] mb-[26px] border-[#dfe1e4]\" />\n <Row>\n <Column className=\"w-[24px]\">\n <Img src={ICON_URL} alt=\"\" width={24} height={24} className=\"rounded-[6px]\" />\n </Column>\n <Column className=\"pl-[8px]\">\n <Link href={ctx.baseUrl} className=\"text-[14px] text-[#b4becc]\">\n {ctx.brandName}\n </Link>\n </Column>\n </Row>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n}\n\nexport function EmailButton({ href, children }: { href: string; children: ReactNode }) {\n return (\n <Section className=\"py-[20px]\">\n <Button\n href={href}\n className=\"rounded-[3px] bg-[#18181b] px-[23px] py-[11px] text-[15px] font-semibold text-white no-underline\"\n >\n {children}\n </Button>\n </Section>\n );\n}\n\nexport function Paragraph({ children }: { children: ReactNode }) {\n return <Text className=\"my-[15px] text-[15px] leading-[1.4] text-[#3c4149]\">{children}</Text>;\n}\n\nexport const PREVIEW_CTX: TemplateContext = {\n brandName: \"Acme LMS\",\n baseUrl: \"http://localhost:8001\",\n studentPortalUrl: \"http://localhost:8002\",\n};\n","import type { EmailTemplateParams, TemplateContext } from \"@headless-lms/core/types\";\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from \"./layout.js\";\n\ntype Params = EmailTemplateParams[\"magicLink\"];\n\nexport const subject = (ctx: TemplateContext, _params: Params) => `Sign in to ${ctx.brandName}`;\n\nexport default function MagicLink({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Sign in\">\n <Paragraph>\n Click the button below to sign in. This link is valid once and expires shortly.\n </Paragraph>\n <EmailButton href={params.url}>Sign in to {ctx.brandName}</EmailButton>\n <Paragraph>If you did not request this, you can ignore this email.</Paragraph>\n </Layout>\n );\n}\n\nMagicLink.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: { url: \"http://localhost:8002/magic?token=demo\" },\n};\n","import type { EmailTemplateParams, TemplateContext } from \"@headless-lms/core/types\";\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from \"./layout.js\";\n\ntype Params = EmailTemplateParams[\"studentInvite\"];\n\nexport const subject = (ctx: TemplateContext, _params: Params) =>\n `You're invited to ${ctx.brandName}`;\n\nexport default function StudentInvite({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Welcome\">\n <Paragraph>\n {params.studentName}, you've been invited to {ctx.brandName}. Create your account to get\n started.\n </Paragraph>\n <EmailButton href={params.inviteUrl}>Create your account</EmailButton>\n <Paragraph>This invitation link is personal โ please don't forward it.</Paragraph>\n </Layout>\n );\n}\n\nStudentInvite.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {\n inviteUrl: \"http://localhost:8002/welcome?token=demo\",\n studentName: \"Sam\",\n },\n};\n","import type { EmailTemplateParams, TemplateContext } from \"@headless-lms/core/types\";\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from \"./layout.js\";\n\ntype Params = EmailTemplateParams[\"memberInvite\"];\n\nexport const subject = (ctx: TemplateContext, _params: Params) =>\n `You've been invited to join ${ctx.brandName}`;\n\nexport default function MemberInvite({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading={`Join ${ctx.brandName}`}>\n <Paragraph>\n {params.inviterName} invited you to join {ctx.brandName} as {params.role}.\n </Paragraph>\n <EmailButton href={params.inviteUrl}>Accept invitation</EmailButton>\n <Paragraph>If you weren't expecting this invitation, you can ignore this email.</Paragraph>\n </Layout>\n );\n}\n\nMemberInvite.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {\n inviteUrl: \"http://localhost:8001/invite?token=demo\",\n inviterName: \"Ann\",\n role: \"Admin\",\n },\n};\n","import type { EmailTemplateParams, TemplateContext } from \"@headless-lms/core/types\";\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from \"./layout.js\";\n\ntype Params = EmailTemplateParams[\"passwordReset\"];\n\nexport const subject = (ctx: TemplateContext, _params: Params) =>\n `Reset your ${ctx.brandName} password`;\n\nexport default function PasswordReset({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Reset your password\">\n <Paragraph>\n Click the button below to choose a new password. The link expires shortly.\n </Paragraph>\n <EmailButton href={params.resetUrl}>Reset password</EmailButton>\n <Paragraph>\n If you did not request a reset, your password is unchanged and you can ignore this email.\n </Paragraph>\n </Layout>\n );\n}\n\nPasswordReset.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: { resetUrl: \"http://localhost:8002/reset?token=demo\" },\n};\n","import type { EmailTemplateParams, TemplateContext } from \"@headless-lms/core/types\";\nimport { Layout, Paragraph, PREVIEW_CTX } from \"./layout.js\";\n\ntype Params = EmailTemplateParams[\"passwordChanged\"];\n\nexport const subject = (ctx: TemplateContext, _params: Params) =>\n `Your ${ctx.brandName} password was changed`;\n\nexport default function PasswordChanged({ ctx }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Your password was changed\">\n <Paragraph>The password for your {ctx.brandName} account was just changed.</Paragraph>\n <Paragraph>If you didn't make this change, reply to this email right away.</Paragraph>\n </Layout>\n );\n}\n\nPasswordChanged.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {},\n};\n","import type { EmailTemplateParams, TemplateContext } from \"@headless-lms/core/types\";\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from \"./layout.js\";\n\ntype Params = EmailTemplateParams[\"emailVerification\"];\n\nexport const subject = (ctx: TemplateContext, _params: Params) =>\n `Verify your email for ${ctx.brandName}`;\n\nexport default function EmailVerification({\n ctx,\n params,\n}: {\n ctx: TemplateContext;\n params: Params;\n}) {\n return (\n <Layout ctx={ctx} heading=\"Verify your email\">\n <Paragraph>Confirm this is your email address to finish setting up your account.</Paragraph>\n <EmailButton href={params.verifyUrl}>Verify email</EmailButton>\n </Layout>\n );\n}\n\nEmailVerification.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: { verifyUrl: \"http://localhost:8002/verify?token=demo\" },\n};\n","import type { EmailTemplateParams, TemplateContext } from \"@headless-lms/core/types\";\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from \"./layout.js\";\n\ntype Params = EmailTemplateParams[\"accessGranted\"];\n\nexport const subject = (_ctx: TemplateContext, params: Params) =>\n `You now have access to ${params.contentTitle}`;\n\nconst PORTAL_PATH: Record<Exclude<Params[\"contentType\"], \"bundle\">, string> = {\n course: \"courses\",\n download: \"downloads\",\n community: \"communities\",\n event: \"events\",\n};\n\nconst BUTTON: Record<Params[\"contentType\"], string> = {\n course: \"Start learning\",\n download: \"View download\",\n community: \"Open community\",\n event: \"Open event\",\n bundle: \"Open your library\",\n};\n\nfunction hrefOf(ctx: TemplateContext, params: Params): string {\n return params.contentType === \"bundle\"\n ? ctx.studentPortalUrl\n : `${ctx.studentPortalUrl}/${PORTAL_PATH[params.contentType]}/${params.contentId}`;\n}\n\nexport default function AccessGranted({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading={`${params.contentTitle} is ready for you`}>\n <Paragraph>\n {params.contentType === \"bundle\"\n ? \"You've been granted access to everything it includes. Jump in whenever you're ready.\"\n : \"You've been granted access. Jump in whenever you're ready.\"}\n </Paragraph>\n <EmailButton href={hrefOf(ctx, params)}>{BUTTON[params.contentType]}</EmailButton>\n </Layout>\n );\n}\n\nAccessGranted.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {\n contentTitle: \"Fly Tying 101\",\n contentId: \"demo\",\n contentType: \"course\",\n },\n};\n","import type { EmailTemplateParams, TemplateContext } from \"@headless-lms/core/types\";\nimport { Layout, Paragraph, PREVIEW_CTX } from \"./layout.js\";\n\ntype Params = EmailTemplateParams[\"accessRevoked\"];\n\nexport const subject = (_ctx: TemplateContext, params: Params) =>\n `Your access to ${params.contentTitle} has ended`;\n\nexport default function AccessRevoked({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Access ended\">\n <Paragraph>\n Your access to {params.contentTitle} has ended. If you think this is a mistake, reply to\n this email.\n </Paragraph>\n </Layout>\n );\n}\n\nAccessRevoked.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {\n contentTitle: \"Fly Tying 101\",\n },\n};\n","import type { EmailTemplateParams, TemplateContext } from \"@headless-lms/core/types\";\nimport { Layout, Paragraph, PREVIEW_CTX } from \"./layout.js\";\n\ntype Params = EmailTemplateParams[\"courseCompleted\"];\n\nexport const subject = (_ctx: TemplateContext, params: Params) =>\n `You completed ${params.courseTitle} ๐`;\n\nexport default function CourseCompleted({ ctx, params }: { ctx: TemplateContext; params: Params }) {\n return (\n <Layout ctx={ctx} heading=\"Congratulations!\">\n <Paragraph>You've completed {params.courseTitle}. Nice work.</Paragraph>\n </Layout>\n );\n}\n\nCourseCompleted.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {\n courseTitle: \"Fly Tying 101\",\n },\n};\n","import type { JSX } from \"react\";\nimport type { EmailTemplateParams, TemplateContext } from \"@headless-lms/core/types\";\nimport { Link, Section, Text } from \"@react-email/components\";\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from \"./layout.js\";\n\nexport function portal(ctx: TemplateContext, path: string): string {\n return `${ctx.studentPortalUrl}${path}`;\n}\n\nexport function defineEmail<K extends keyof EmailTemplateParams>(opts: {\n subject: (ctx: TemplateContext, params: EmailTemplateParams[K]) => string;\n heading: (params: EmailTemplateParams[K]) => string;\n lines: (params: EmailTemplateParams[K]) => string[];\n button?: (\n ctx: TemplateContext,\n params: EmailTemplateParams[K],\n ) => { href: string; label: string };\n preview: EmailTemplateParams[K];\n}): {\n subject: (ctx: TemplateContext, params: EmailTemplateParams[K]) => string;\n Component: (props: { ctx: TemplateContext; params: EmailTemplateParams[K] }) => JSX.Element;\n} {\n function Component({ ctx, params }: { ctx: TemplateContext; params: EmailTemplateParams[K] }) {\n const button = opts.button?.(ctx, params);\n return (\n <Layout ctx={ctx} heading={opts.heading(params)}>\n {opts.lines(params).map((line, index) => (\n <Paragraph key={index}>{line}</Paragraph>\n ))}\n {button ? <EmailButton href={button.href}>{button.label}</EmailButton> : null}\n </Layout>\n );\n }\n Component.PreviewProps = { ctx: PREVIEW_CTX, params: opts.preview };\n return { subject: opts.subject, Component };\n}\n\nconst community = (ctx: TemplateContext, id: string) => portal(ctx, `/communities/${id}`);\nconst space = (ctx: TemplateContext, communityId: string, spaceId: string) =>\n portal(ctx, `/communities/${communityId}/spaces/${spaceId}`);\nconst post = (ctx: TemplateContext, communityId: string, postId: string) =>\n portal(ctx, `/communities/${communityId}/posts/${postId}`);\nconst comment = (ctx: TemplateContext, communityId: string, postId: string, commentId: string) =>\n `${post(ctx, communityId, postId)}#${commentId}`;\nconst chat = (ctx: TemplateContext, communityId: string, chatId: string) =>\n portal(ctx, `/communities/${communityId}/chats/${chatId}`);\n\nfunction accessEnds(value: string): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return value;\n }\n return new Intl.DateTimeFormat(\"en-US\", {\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n timeZone: \"UTC\",\n }).format(date);\n}\n\nexport const welcomeToCommunity = defineEmail<\"welcomeToCommunity\">({\n subject: (_ctx, params) => `Welcome to ${params.communityTitle}`,\n heading: (params) => params.communityTitle,\n lines: (params) => [\n params.spaceNames.length > 0\n ? `You can open ${params.spaceNames.join(\", \")}.`\n : \"You're a member.\",\n ],\n button: (ctx, params) => ({ href: community(ctx, params.communityId), label: \"Open community\" }),\n preview: { communityTitle: \"Founders\", communityId: \"cmy_1\", spaceNames: [\"Announcements\"] },\n});\n\nexport const membershipEndingSoon = defineEmail<\"membershipEndingSoon\">({\n subject: (_ctx, params) => `${params.communityTitle} ends soon`,\n heading: (params) => `${params.communityTitle} ends soon`,\n lines: (params) => [`Your access ends ${accessEnds(params.expiresAt)}.`],\n button: (ctx, params) => ({ href: community(ctx, params.communityId), label: \"Renew\" }),\n preview: {\n communityTitle: \"Founders\",\n communityId: \"cmy_1\",\n expiresAt: \"2026-10-28T00:00:00.000Z\",\n },\n});\n\nfunction communityTitles(params: EmailTemplateParams[\"membershipEnded\"]): string {\n return params.communities.map((item) => item.communityTitle).join(\", \");\n}\n\nexport const membershipEnded = defineEmail<\"membershipEnded\">({\n subject: (_ctx, params) => `${communityTitles(params)} has ended`,\n heading: (params) => `${communityTitles(params)} has ended`,\n lines: (params) => [\n params.communities.length === 1\n ? \"Your access to this community has ended.\"\n : \"Your access to these communities has ended.\",\n ],\n button: (ctx, params) => {\n const [only] = params.communities;\n return params.communities.length === 1 && only\n ? { href: community(ctx, only.communityId), label: \"Renew\" }\n : { href: portal(ctx, \"/communities\"), label: \"Open communities\" };\n },\n preview: { communities: [{ communityId: \"cmy_1\", communityTitle: \"Founders\" }] },\n});\n\nexport const newPostInSpace = defineEmail<\"newPostInSpace\">({\n subject: (_ctx, params) => `${params.authorName} posted in ${params.spaceName}`,\n heading: (params) => params.postTitle,\n lines: (params) => [`${params.authorName} in ${params.spaceName}`, params.excerpt],\n button: (ctx, params) => ({\n href: post(ctx, params.communityId, params.postId),\n label: \"Read post\",\n }),\n preview: {\n spaceName: \"Announcements\",\n postTitle: \"Hello\",\n authorName: \"Ann\",\n excerpt: \"A short note\",\n postId: \"pst_1\",\n communityId: \"cmy_1\",\n },\n});\n\nexport const yourPostWasPublished = defineEmail<\"yourPostWasPublished\">({\n subject: (_ctx, params) => `Your post was published in ${params.spaceName}`,\n heading: (params) => params.postTitle,\n lines: (params) => [`It's live in ${params.spaceName}.`],\n button: (ctx, params) => ({\n href: post(ctx, params.communityId, params.postId),\n label: \"View post\",\n }),\n preview: {\n postTitle: \"Hello\",\n spaceName: \"Announcements\",\n postId: \"pst_1\",\n communityId: \"cmy_1\",\n },\n});\n\nexport const yourPostWasRemoved = defineEmail<\"yourPostWasRemoved\">({\n subject: (_ctx, params) => `Your post was removed from ${params.spaceName}`,\n heading: (params) => params.postTitle,\n lines: (params) => [`It was removed from ${params.spaceName}.`],\n button: (ctx, params) => ({\n href: space(ctx, params.communityId, params.spaceId),\n label: \"Open space\",\n }),\n preview: {\n postTitle: \"Hello\",\n spaceName: \"Announcements\",\n spaceId: \"spc_1\",\n communityId: \"cmy_1\",\n },\n});\n\nexport const newCommentOnPost = defineEmail<\"newCommentOnPost\">({\n subject: (_ctx, params) => `${params.commenterName} commented on ${params.postTitle}`,\n heading: (params) => params.postTitle,\n lines: (params) => [params.commenterName, params.excerpt],\n button: (ctx, params) => ({\n href: comment(ctx, params.communityId, params.postId, params.commentId),\n label: \"View comment\",\n }),\n preview: {\n postTitle: \"Hello\",\n commenterName: \"Sam\",\n excerpt: \"Nice\",\n commentId: \"cmt_1\",\n postId: \"pst_1\",\n communityId: \"cmy_1\",\n },\n});\n\nexport const replyToYourComment = defineEmail<\"replyToYourComment\">({\n subject: (_ctx, params) => `${params.commenterName} replied on ${params.postTitle}`,\n heading: (params) => params.postTitle,\n lines: (params) => [params.commenterName, params.excerpt],\n button: (ctx, params) => ({\n href: comment(ctx, params.communityId, params.postId, params.commentId),\n label: \"View reply\",\n }),\n preview: {\n postTitle: \"Hello\",\n commenterName: \"Sam\",\n excerpt: \"Thanks\",\n commentId: \"cmt_2\",\n postId: \"pst_1\",\n communityId: \"cmy_1\",\n },\n});\n\nexport const yourCommentWasRemoved = defineEmail<\"yourCommentWasRemoved\">({\n subject: (_ctx, params) => `Your comment was removed from ${params.postTitle}`,\n heading: (params) => params.postTitle,\n lines: () => [\"Your comment was removed.\"],\n button: (ctx, params) => ({\n href: post(ctx, params.communityId, params.postId),\n label: \"View post\",\n }),\n preview: { postTitle: \"Hello\", postId: \"pst_1\", communityId: \"cmy_1\" },\n});\n\nexport const requestApproved = defineEmail<\"requestApproved\">({\n subject: (_ctx, params) => `You're in ${params.spaceName}`,\n heading: (params) => params.spaceName,\n lines: (params) => [`Your request to join ${params.spaceName} was approved.`],\n button: (ctx, params) => ({\n href: space(ctx, params.communityId, params.spaceId),\n label: \"Open space\",\n }),\n preview: { spaceName: \"SaaS\", spaceId: \"spc_1\", communityId: \"cmy_1\" },\n});\n\nexport const requestDeclined = defineEmail<\"requestDeclined\">({\n subject: (_ctx, params) => `Request declined for ${params.spaceName}`,\n heading: (params) => params.spaceName,\n lines: (params) => [`Your request to join ${params.spaceName} was declined.`],\n button: (ctx, params) => ({ href: community(ctx, params.communityId), label: \"Open community\" }),\n preview: { spaceName: \"SaaS\", communityId: \"cmy_1\" },\n});\n\nexport const invitedToSpace = defineEmail<\"invitedToSpace\">({\n subject: (_ctx, params) => `${params.inviterName} invited you to ${params.spaceName}`,\n heading: (params) => params.spaceName,\n lines: (params) => [`${params.inviterName} invited you.`],\n button: (ctx, params) => ({\n href: space(ctx, params.communityId, params.spaceId),\n label: \"Accept\",\n }),\n preview: {\n spaceName: \"SaaS\",\n inviterName: \"Ann\",\n spaceId: \"spc_1\",\n communityId: \"cmy_1\",\n },\n});\n\nexport const messageRequest = defineEmail<\"messageRequest\">({\n subject: (_ctx, params) => `${params.senderName} sent a message request`,\n heading: (params) => params.senderName,\n lines: (params) => [params.excerpt],\n button: (ctx, params) => ({\n href: chat(ctx, params.communityId, params.chatId),\n label: \"View request\",\n }),\n preview: { senderName: \"Ann\", excerpt: \"Hello\", chatId: \"cht_1\", communityId: \"cmy_1\" },\n});\n\nexport const newMessage = defineEmail<\"newMessage\">({\n subject: (_ctx, params) => `${params.senderName} in ${params.chatTitle}`,\n heading: (params) => params.chatTitle,\n lines: (params) => [`${params.senderName}: ${params.excerpt}`],\n button: (ctx, params) => ({\n href: chat(ctx, params.communityId, params.chatId),\n label: \"Open chat\",\n }),\n preview: {\n senderName: \"Ann\",\n chatTitle: \"Group chat\",\n excerpt: \"Hello\",\n chatId: \"cht_1\",\n communityId: \"cmy_1\",\n },\n});\n\nexport const addedToGroupChat = defineEmail<\"addedToGroupChat\">({\n subject: (_ctx, params) => `${params.adderName} added you to a chat`,\n heading: () => \"You were added to a chat\",\n lines: (params) => [`${params.adderName} added you.`, params.participantNames.join(\", \")],\n button: (ctx, params) => ({\n href: chat(ctx, params.communityId, params.chatId),\n label: \"Open chat\",\n }),\n preview: {\n adderName: \"Ann\",\n participantNames: [\"Ann\", \"Sam\"],\n chatId: \"cht_1\",\n communityId: \"cmy_1\",\n },\n});\n\nconst ROLE_PATH: Record<string, string> = {\n course: \"courses\",\n download: \"downloads\",\n community: \"communities\",\n event: \"events\",\n};\n\nexport const roleAssigned = defineEmail<\"roleAssigned\">({\n subject: (_ctx, params) => `You are now ${params.roleName} ${params.place}`,\n heading: (params) => `You are now ${params.roleName}`,\n lines: (params) => [`You are now ${params.roleName} ${params.place}.`],\n button: (ctx, params) =>\n params.contentId !== null && params.contentType !== null\n ? {\n href: `${ctx.baseUrl}/${ROLE_PATH[params.contentType] ?? \"\"}/${params.contentId}`,\n label: \"Open\",\n }\n : { href: ctx.baseUrl, label: \"Open\" },\n preview: {\n roleName: \"Moderator\",\n place: \"of Founders\",\n contentId: \"cmy_1\",\n contentType: \"community\",\n },\n});\n\ntype DigestParams = EmailTemplateParams[\"digest\"];\n\nfunction commentsLabel(count: number): string {\n return count === 1 ? \"1 comment\" : `${count} comments`;\n}\n\nfunction Digest({ ctx, params }: { ctx: TemplateContext; params: DigestParams }) {\n return (\n <Layout ctx={ctx} heading={`${params.communityTitle} digest`}>\n <Paragraph>{\"Here's what you haven't seen.\"}</Paragraph>\n {params.posts.map((item) => (\n <Section key={item.postId} className=\"my-[12px]\">\n <Link\n href={post(ctx, params.communityId, item.postId)}\n className=\"text-[16px] font-semibold text-[#18181b]\"\n >\n {item.title}\n </Link>\n <Text className=\"my-[2px] text-[14px] leading-[1.4] text-[#6b7280]\">\n {`${item.authorName} in ${item.spaceName} ยท ${commentsLabel(item.commentCount)}`}\n </Text>\n </Section>\n ))}\n <EmailButton href={community(ctx, params.communityId)}>Open community</EmailButton>\n </Layout>\n );\n}\n\nDigest.PreviewProps = {\n ctx: PREVIEW_CTX,\n params: {\n communityTitle: \"Founders\",\n communityId: \"cmy_1\",\n from: \"2026-10-29T07:00:00.000Z\",\n to: \"2026-11-05T07:00:00.000Z\",\n posts: [\n {\n postId: \"pst_1\",\n title: \"Welcome, everyone\",\n authorName: \"Sam\",\n spaceName: \"Announcements\",\n commentCount: 4,\n },\n ],\n },\n};\n\nexport const digest = {\n subject: (_ctx: TemplateContext, params: DigestParams) => `${params.communityTitle} digest`,\n Component: Digest,\n};\n\nexport const postAwaitingReview = defineEmail<\"postAwaitingReview\">({\n subject: (_ctx, params) => `Post awaiting review in ${params.spaceName}`,\n heading: (params) => params.postTitle,\n lines: (params) => [`${params.authorName} submitted a post in ${params.spaceName}.`],\n button: (ctx, params) => ({\n href: space(ctx, params.communityId, params.spaceId),\n label: \"Review\",\n }),\n preview: {\n spaceName: \"Announcements\",\n postTitle: \"Hello\",\n authorName: \"Sam\",\n spaceId: \"spc_1\",\n communityId: \"cmy_1\",\n },\n});\n\nexport const joinRequest = defineEmail<\"joinRequest\">({\n subject: (_ctx, params) => `${params.memberName} requested ${params.spaceName}`,\n heading: (params) => params.spaceName,\n lines: (params) => [`${params.memberName} asked to join. Seats left: ${params.seatsLeft}.`],\n button: (ctx, params) => ({\n href: space(ctx, params.communityId, params.spaceId),\n label: \"Review request\",\n }),\n preview: {\n spaceName: \"SaaS\",\n memberName: \"Sam\",\n seatsLeft: \"3\",\n spaceId: \"spc_1\",\n communityId: \"cmy_1\",\n },\n});\n\nexport const somethingWasFlagged = defineEmail<\"somethingWasFlagged\">({\n subject: (_ctx, params) => `Something was flagged in ${params.spaceName}`,\n heading: (params) => params.spaceName,\n lines: (params) => [params.reason, params.excerpt],\n button: (ctx, params) => ({\n href: space(ctx, params.communityId, params.spaceId),\n label: \"Review\",\n }),\n preview: {\n spaceName: \"Announcements\",\n excerpt: \"Hello\",\n reason: \"Spam\",\n spaceId: \"spc_1\",\n communityId: \"cmy_1\",\n },\n});\n\nexport const messageWasFlagged = defineEmail<\"messageWasFlagged\">({\n subject: () => \"A message was flagged\",\n heading: () => \"A message was flagged\",\n lines: (params) => [params.reason],\n button: (ctx, params) => ({ href: community(ctx, params.communityId), label: \"Review\" }),\n preview: { reason: \"Spam\", communityId: \"cmy_1\" },\n});\n\nexport const postReacted = defineEmail<\"postReacted\">({\n subject: (_ctx, params) => `${params.reactorName} reacted to your post`,\n heading: (params) => params.postTitle,\n lines: (params) => [`${params.reactorName} reacted ${params.reaction} to your post.`],\n button: (ctx, params) => ({\n href: post(ctx, params.communityId, params.postId),\n label: \"View post\",\n }),\n preview: {\n postTitle: \"Hello\",\n reactorName: \"Sam\",\n reaction: \"๐\",\n postId: \"pst_1\",\n communityId: \"cmy_1\",\n },\n});\n\nexport const commentReacted = defineEmail<\"commentReacted\">({\n subject: (_ctx, params) => `${params.reactorName} reacted to your comment`,\n heading: (params) => params.postTitle,\n lines: (params) => [`${params.reactorName} reacted ${params.reaction} to:`, params.excerpt],\n button: (ctx, params) => ({\n href: comment(ctx, params.communityId, params.postId, params.commentId),\n label: \"View comment\",\n }),\n preview: {\n postTitle: \"Hello\",\n excerpt: \"Nice\",\n reactorName: \"Sam\",\n reaction: \"๐\",\n commentId: \"cmt_1\",\n postId: \"pst_1\",\n communityId: \"cmy_1\",\n },\n});\n\nfunction mentionedIn(params: EmailTemplateParams[\"mention\"]): string {\n return \"postTitle\" in params ? params.postTitle : params.chatTitle;\n}\n\nexport const mention = defineEmail<\"mention\">({\n subject: (_ctx, params) => `${params.authorName} mentioned you in ${mentionedIn(params)}`,\n heading: (params) => mentionedIn(params),\n lines: (params) => [params.authorName, params.excerpt],\n button: (ctx, params) =>\n \"postTitle\" in params\n ? {\n href: params.commentId\n ? comment(ctx, params.communityId, params.postId, params.commentId)\n : post(ctx, params.communityId, params.postId),\n label: \"View\",\n }\n : { href: chat(ctx, params.communityId, params.chatId), label: \"Open chat\" },\n preview: {\n authorName: \"Sam\",\n excerpt: \"Thanks @Ann\",\n communityId: \"cmy_1\",\n postTitle: \"Hello\",\n postId: \"pst_1\",\n commentId: \"cmt_1\",\n },\n});\n\nexport const messageReacted = defineEmail<\"messageReacted\">({\n subject: (_ctx, params) => `${params.reactorName} reacted to your message`,\n heading: () => \"A reaction to your message\",\n lines: (params) => [`${params.reactorName} reacted ${params.reaction} to:`, params.excerpt],\n button: (ctx, params) => ({\n href: chat(ctx, params.communityId, params.chatId),\n label: \"Open chat\",\n }),\n preview: {\n excerpt: \"Hello\",\n reactorName: \"Sam\",\n reaction: \"๐\",\n chatId: \"cht_1\",\n communityId: \"cmy_1\",\n },\n});\n","import type { TemplateContext } from \"@headless-lms/core/types\";\nimport { defineEmail, portal } from \"./community.js\";\n\nconst activity = (ctx: TemplateContext, courseId: string, activityId: string) =>\n portal(ctx, `/courses/${courseId}?activity=${activityId}`);\n\nexport const courseActivityAdded = defineEmail<\"courseActivityAdded\">({\n subject: (_ctx, params) => `New in ${params.courseTitle}: ${params.activityTitle}`,\n heading: (params) => params.activityTitle,\n lines: (params) => [`${params.courseTitle}, ${params.moduleTitle}`],\n button: (ctx, params) => ({\n href: activity(ctx, params.courseId, params.activityId),\n label: \"Open lesson\",\n }),\n preview: {\n courseTitle: \"Fly Tying 101\",\n moduleTitle: \"Basics\",\n activityTitle: \"Choosing hooks\",\n courseId: \"crs_1\",\n activityId: \"act_1\",\n },\n});\n\nexport const activityCommentCreated = defineEmail<\"activityCommentCreated\">({\n subject: (_ctx, params) => `${params.commenterName} commented on ${params.activityTitle}`,\n heading: (params) => params.activityTitle,\n lines: (params) => [params.courseTitle, params.commenterName, params.excerpt],\n button: (ctx, params) => ({\n href: activity(ctx, params.courseId, params.activityId),\n label: \"View comment\",\n }),\n preview: {\n activityTitle: \"Choosing hooks\",\n courseTitle: \"Fly Tying 101\",\n commenterName: \"Sam\",\n excerpt: \"Nice\",\n courseId: \"crs_1\",\n activityId: \"act_1\",\n commentId: \"cmt_1\",\n },\n});\n\nexport const activityCommentRemoved = defineEmail<\"activityCommentRemoved\">({\n subject: (_ctx, params) => `Your comment was removed from ${params.activityTitle}`,\n heading: (params) => params.activityTitle,\n lines: (params) => [`Your comment in ${params.courseTitle} was removed.`],\n button: (ctx, params) => ({\n href: activity(ctx, params.courseId, params.activityId),\n label: \"Open lesson\",\n }),\n preview: {\n activityTitle: \"Choosing hooks\",\n courseTitle: \"Fly Tying 101\",\n courseId: \"crs_1\",\n activityId: \"act_1\",\n },\n});\n\nexport const activityCommentReacted = defineEmail<\"activityCommentReacted\">({\n subject: (_ctx, params) => `${params.reactorName} reacted to your comment`,\n heading: (params) => params.activityTitle,\n lines: (params) => [`${params.reactorName} reacted ${params.reaction} to:`, params.excerpt],\n button: (ctx, params) => ({\n href: activity(ctx, params.courseId, params.activityId),\n label: \"View comment\",\n }),\n preview: {\n activityTitle: \"Choosing hooks\",\n courseTitle: \"Fly Tying 101\",\n excerpt: \"Nice\",\n reactorName: \"Sam\",\n reaction: \"๐\",\n courseId: \"crs_1\",\n activityId: \"act_1\",\n commentId: \"cmt_1\",\n },\n});\n\nexport const activityCommentFlagged = defineEmail<\"activityCommentFlagged\">({\n subject: (_ctx, params) => `A comment was flagged in ${params.activityTitle}`,\n heading: (params) => params.activityTitle,\n lines: (params) => [params.courseTitle, params.reason, params.excerpt],\n button: (ctx, params) => ({\n href: activity(ctx, params.courseId, params.activityId),\n label: \"Review\",\n }),\n preview: {\n activityTitle: \"Choosing hooks\",\n courseTitle: \"Fly Tying 101\",\n excerpt: \"Hello\",\n reason: \"Spam\",\n courseId: \"crs_1\",\n activityId: \"act_1\",\n },\n});\n\nexport const activityMention = defineEmail<\"activityMention\">({\n subject: (_ctx, params) => `${params.authorName} mentioned you in ${params.activityTitle}`,\n heading: (params) => params.activityTitle,\n lines: (params) => [params.courseTitle, params.authorName, params.excerpt],\n button: (ctx, params) => ({\n href: activity(ctx, params.courseId, params.activityId),\n label: \"View\",\n }),\n preview: {\n authorName: \"Sam\",\n excerpt: \"Thanks @Ann\",\n activityTitle: \"Choosing hooks\",\n courseTitle: \"Fly Tying 101\",\n courseId: \"crs_1\",\n activityId: \"act_1\",\n },\n});\n","import type {\n EmailTemplateParams,\n EventEmailParams,\n TemplateContext,\n} from \"@headless-lms/core/types\";\nimport { Link, Section } from \"@react-email/components\";\nimport { defineEmail, portal } from \"./community.js\";\nimport { EmailButton, Layout, Paragraph, PREVIEW_CTX } from \"./layout.js\";\n\nconst PREVIEW_EVENT: EventEmailParams = {\n eventId: \"evn_1\",\n eventTitle: \"Conversation practice\",\n startsAt: \"2026-05-12T16:00:00.000Z\",\n endsAt: \"2026-05-12T17:00:00.000Z\",\n timeZone: \"Europe/London\",\n};\n\nexport function eventPage(ctx: TemplateContext, eventId: string): string {\n return portal(ctx, `/events/${eventId}`);\n}\n\nfunction formatIn(value: string, timeZone: string, options: Intl.DateTimeFormatOptions): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) {\n return value;\n }\n try {\n return new Intl.DateTimeFormat(\"en-US\", { ...options, timeZone }).format(date);\n } catch {\n return new Intl.DateTimeFormat(\"en-US\", { ...options, timeZone: \"UTC\" }).format(date);\n }\n}\n\nexport function eventWhen(params: EventEmailParams): string {\n const day = formatIn(params.startsAt, params.timeZone, {\n weekday: \"long\",\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n });\n const time = { hour: \"numeric\", minute: \"2-digit\" } as const;\n const from = formatIn(params.startsAt, params.timeZone, time);\n const to = formatIn(params.endsAt, params.timeZone, time);\n return `${day}, ${from} โ ${to} (${params.timeZone})`;\n}\n\nfunction calendarStamp(value: string): string {\n return new Date(value)\n .toISOString()\n .replace(/[-:]/g, \"\")\n .replace(/\\.\\d{3}/, \"\");\n}\n\nexport function googleCalendarUrl(ctx: TemplateContext, params: EventEmailParams): string {\n const query = new URLSearchParams({\n action: \"TEMPLATE\",\n text: params.eventTitle,\n dates: `${calendarStamp(params.startsAt)}/${calendarStamp(params.endsAt)}`,\n details: eventPage(ctx, params.eventId),\n ctz: params.timeZone,\n });\n return `https://calendar.google.com/calendar/render?${query.toString()}`;\n}\n\nexport function outlookCalendarUrl(ctx: TemplateContext, params: EventEmailParams): string {\n const query = new URLSearchParams({\n path: \"/calendar/action/compose\",\n rru: \"addevent\",\n subject: params.eventTitle,\n startdt: new Date(params.startsAt).toISOString(),\n enddt: new Date(params.endsAt).toISOString(),\n body: eventPage(ctx, params.eventId),\n });\n return `https://outlook.live.com/calendar/0/action/compose?${query.toString()}`;\n}\n\ntype Granted = EmailTemplateParams[\"eventGranted\"];\n\nfunction EventGranted({ ctx, params }: { ctx: TemplateContext; params: Granted }) {\n return (\n <Layout ctx={ctx} heading={`You're going to ${params.eventTitle}`}>\n <Paragraph>{eventWhen(params)}</Paragraph>\n <EmailButton href={eventPage(ctx, params.eventId)}>Open event</EmailButton>\n <Section>\n <Paragraph>\n <Link href={googleCalendarUrl(ctx, params)}>Add to Google Calendar</Link>\n {\" ยท \"}\n <Link href={outlookCalendarUrl(ctx, params)}>Add to Outlook</Link>\n </Paragraph>\n </Section>\n </Layout>\n );\n}\n\nEventGranted.PreviewProps = { ctx: PREVIEW_CTX, params: PREVIEW_EVENT };\n\nexport const eventGranted = {\n subject: (_ctx: TemplateContext, params: Granted) => `You're going to ${params.eventTitle}`,\n Component: EventGranted,\n};\n\nconst CHANGED: Record<EmailTemplateParams[\"eventChanged\"][\"changed\"], string> = {\n time: \"The time has changed.\",\n location: \"The location has changed. Open the event for the new details.\",\n time_and_location: \"The time and the location have changed. Open the event for the new details.\",\n};\n\nconst open = (ctx: TemplateContext, params: EventEmailParams) => ({\n href: eventPage(ctx, params.eventId),\n label: \"Open event\",\n});\n\nexport const eventStartingSoon = defineEmail<\"eventStartingSoon\">({\n subject: (_ctx, params) => `${params.eventTitle} starts in ${params.leadText}`,\n heading: (params) => `${params.eventTitle} starts in ${params.leadText}`,\n lines: (params) => [eventWhen(params), \"Open the event for the link.\"],\n button: open,\n preview: { ...PREVIEW_EVENT, leadText: \"1 hour\" },\n});\n\nexport const eventChanged = defineEmail<\"eventChanged\">({\n subject: (_ctx, params) => `${params.eventTitle} has changed`,\n heading: (params) => `${params.eventTitle} has changed`,\n lines: (params) => [CHANGED[params.changed], eventWhen(params)],\n button: open,\n preview: { ...PREVIEW_EVENT, changed: \"time\" },\n});\n\nexport const eventCanceled = defineEmail<\"eventCanceled\">({\n subject: (_ctx, params) => `${params.eventTitle} was canceled`,\n heading: (params) => `${params.eventTitle} was canceled`,\n lines: (params) => [`It was planned for ${eventWhen(params)}.`],\n button: open,\n preview: PREVIEW_EVENT,\n});\n\nexport const eventRevoked = defineEmail<\"eventRevoked\">({\n subject: (_ctx, params) => `You're no longer going to ${params.eventTitle}`,\n heading: (params) => `You're no longer going to ${params.eventTitle}`,\n lines: (params) => [`You've been removed from the event on ${eventWhen(params)}.`],\n button: open,\n preview: PREVIEW_EVENT,\n});\n","// Default TemplateRenderer: react-email components rendered at call time.\nimport { render } from \"@react-email/render\";\nimport type { JSX } from \"react\";\nimport type {\n EmailContent,\n EmailTemplateId,\n EmailTemplateParams,\n TemplateContext,\n TemplateRenderer,\n} from \"@headless-lms/core/types\";\nimport MagicLink, { subject as magicLink } from \"./emails/magic-link.js\";\nimport StudentInvite, { subject as studentInvite } from \"./emails/student-invite.js\";\nimport MemberInvite, { subject as memberInvite } from \"./emails/member-invite.js\";\nimport PasswordReset, { subject as passwordReset } from \"./emails/password-reset.js\";\nimport PasswordChanged, { subject as passwordChanged } from \"./emails/password-changed.js\";\nimport EmailVerification, { subject as emailVerification } from \"./emails/email-verification.js\";\nimport AccessGranted, { subject as accessGranted } from \"./emails/access-granted.js\";\nimport AccessRevoked, { subject as accessRevoked } from \"./emails/access-revoked.js\";\nimport CourseCompleted, { subject as courseCompleted } from \"./emails/course-completed.js\";\nimport {\n addedToGroupChat,\n commentReacted,\n digest,\n invitedToSpace,\n joinRequest,\n membershipEnded,\n membershipEndingSoon,\n mention,\n messageReacted,\n messageRequest,\n messageWasFlagged,\n newCommentOnPost,\n newMessage,\n newPostInSpace,\n postAwaitingReview,\n postReacted,\n replyToYourComment,\n requestApproved,\n requestDeclined,\n somethingWasFlagged,\n welcomeToCommunity,\n roleAssigned,\n yourCommentWasRemoved,\n yourPostWasPublished,\n yourPostWasRemoved,\n} from \"./emails/community.js\";\nimport {\n activityCommentCreated,\n activityCommentFlagged,\n activityCommentReacted,\n activityCommentRemoved,\n activityMention,\n courseActivityAdded,\n} from \"./emails/course-activity.js\";\nimport {\n eventCanceled,\n eventChanged,\n eventGranted,\n eventRevoked,\n eventStartingSoon,\n} from \"./emails/events.js\";\n\ninterface Entry<K extends EmailTemplateId> {\n subject: (ctx: TemplateContext, params: EmailTemplateParams[K]) => string;\n Component: (props: { ctx: TemplateContext; params: EmailTemplateParams[K] }) => JSX.Element;\n}\n\n// The catalog is closed: a missing key here is a compile error.\nconst registry: { [K in EmailTemplateId]: Entry<K> } = {\n magicLink: { subject: magicLink, Component: MagicLink },\n studentInvite: { subject: studentInvite, Component: StudentInvite },\n memberInvite: { subject: memberInvite, Component: MemberInvite },\n passwordReset: { subject: passwordReset, Component: PasswordReset },\n passwordChanged: { subject: passwordChanged, Component: PasswordChanged },\n emailVerification: { subject: emailVerification, Component: EmailVerification },\n accessGranted: { subject: accessGranted, Component: AccessGranted },\n accessRevoked: { subject: accessRevoked, Component: AccessRevoked },\n courseCompleted: { subject: courseCompleted, Component: CourseCompleted },\n welcomeToCommunity: {\n subject: welcomeToCommunity.subject,\n Component: welcomeToCommunity.Component,\n },\n membershipEndingSoon: {\n subject: membershipEndingSoon.subject,\n Component: membershipEndingSoon.Component,\n },\n membershipEnded: { subject: membershipEnded.subject, Component: membershipEnded.Component },\n newPostInSpace: { subject: newPostInSpace.subject, Component: newPostInSpace.Component },\n yourPostWasPublished: {\n subject: yourPostWasPublished.subject,\n Component: yourPostWasPublished.Component,\n },\n yourPostWasRemoved: {\n subject: yourPostWasRemoved.subject,\n Component: yourPostWasRemoved.Component,\n },\n newCommentOnPost: { subject: newCommentOnPost.subject, Component: newCommentOnPost.Component },\n replyToYourComment: {\n subject: replyToYourComment.subject,\n Component: replyToYourComment.Component,\n },\n yourCommentWasRemoved: {\n subject: yourCommentWasRemoved.subject,\n Component: yourCommentWasRemoved.Component,\n },\n requestApproved: { subject: requestApproved.subject, Component: requestApproved.Component },\n requestDeclined: { subject: requestDeclined.subject, Component: requestDeclined.Component },\n invitedToSpace: { subject: invitedToSpace.subject, Component: invitedToSpace.Component },\n messageRequest: { subject: messageRequest.subject, Component: messageRequest.Component },\n newMessage: { subject: newMessage.subject, Component: newMessage.Component },\n addedToGroupChat: { subject: addedToGroupChat.subject, Component: addedToGroupChat.Component },\n roleAssigned: { subject: roleAssigned.subject, Component: roleAssigned.Component },\n digest: { subject: digest.subject, Component: digest.Component },\n postAwaitingReview: {\n subject: postAwaitingReview.subject,\n Component: postAwaitingReview.Component,\n },\n joinRequest: { subject: joinRequest.subject, Component: joinRequest.Component },\n somethingWasFlagged: {\n subject: somethingWasFlagged.subject,\n Component: somethingWasFlagged.Component,\n },\n messageWasFlagged: {\n subject: messageWasFlagged.subject,\n Component: messageWasFlagged.Component,\n },\n postReacted: { subject: postReacted.subject, Component: postReacted.Component },\n commentReacted: { subject: commentReacted.subject, Component: commentReacted.Component },\n mention: { subject: mention.subject, Component: mention.Component },\n messageReacted: { subject: messageReacted.subject, Component: messageReacted.Component },\n courseActivityAdded: {\n subject: courseActivityAdded.subject,\n Component: courseActivityAdded.Component,\n },\n activityCommentCreated: {\n subject: activityCommentCreated.subject,\n Component: activityCommentCreated.Component,\n },\n activityCommentRemoved: {\n subject: activityCommentRemoved.subject,\n Component: activityCommentRemoved.Component,\n },\n activityCommentReacted: {\n subject: activityCommentReacted.subject,\n Component: activityCommentReacted.Component,\n },\n activityCommentFlagged: {\n subject: activityCommentFlagged.subject,\n Component: activityCommentFlagged.Component,\n },\n activityMention: { subject: activityMention.subject, Component: activityMention.Component },\n eventGranted: { subject: eventGranted.subject, Component: eventGranted.Component },\n eventStartingSoon: {\n subject: eventStartingSoon.subject,\n Component: eventStartingSoon.Component,\n },\n eventChanged: { subject: eventChanged.subject, Component: eventChanged.Component },\n eventCanceled: { subject: eventCanceled.subject, Component: eventCanceled.Component },\n eventRevoked: { subject: eventRevoked.subject, Component: eventRevoked.Component },\n};\n\nexport class ReactEmailTemplateRenderer implements TemplateRenderer {\n async render<K extends EmailTemplateId>(\n id: K,\n ctx: TemplateContext,\n params: EmailTemplateParams[K],\n ): Promise<EmailContent> {\n const entry = registry[id] as Entry<K>;\n const element = <entry.Component ctx={ctx} params={params} />;\n const [html, text] = await Promise.all([render(element), render(element, { plainText: true })]);\n return { subject: entry.subject(ctx, params), html, text };\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@headless-lms/adapter-email-templates",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"@react-email/render": "^2.1.0",
|
|
16
16
|
"react": "19.2.4",
|
|
17
17
|
"react-dom": "19.2.4",
|
|
18
|
-
"@headless-lms/core": "0.
|
|
18
|
+
"@headless-lms/core": "0.6.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@react-email/ui": "6.9.0",
|