brookmind-emails 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modelfy/config.d.ts +4 -0
- package/dist/modelfy/config.d.ts.map +1 -1
- package/dist/modelfy/config.js +6 -0
- package/dist/modelfy/index.d.ts +4 -2
- package/dist/modelfy/index.d.ts.map +1 -1
- package/dist/modelfy/index.js +11 -1
- package/dist/modelfy/templates/GrantCreditsEmail.d.ts.map +1 -1
- package/dist/modelfy/templates/GrantCreditsEmail.js +137 -50
- package/dist/modelfy/templates/OtpEmail.d.ts.map +1 -1
- package/dist/modelfy/templates/OtpEmail.js +108 -30
- package/dist/modelfy/templates/PromoSubscriptionEmail.d.ts.map +1 -1
- package/dist/modelfy/templates/PromoSubscriptionEmail.js +128 -41
- package/dist/modelfy/templates/WelcomeEmail.d.ts +6 -0
- package/dist/modelfy/templates/WelcomeEmail.d.ts.map +1 -0
- package/dist/modelfy/templates/WelcomeEmail.js +377 -0
- package/dist/modelfy/templates/index.d.ts +1 -0
- package/dist/modelfy/templates/index.d.ts.map +1 -1
- package/dist/modelfy/templates/index.js +1 -0
- package/package.json +3 -1
- package/src/modelfy/config.ts +6 -0
- package/src/modelfy/index.ts +16 -2
- package/src/modelfy/templates/GrantCreditsEmail.tsx +229 -82
- package/src/modelfy/templates/OtpEmail.tsx +185 -40
- package/src/modelfy/templates/PromoSubscriptionEmail.tsx +234 -79
- package/src/modelfy/templates/WelcomeEmail.tsx +619 -0
- package/src/modelfy/templates/index.ts +1 -0
package/src/modelfy/index.ts
CHANGED
|
@@ -5,12 +5,13 @@ import {
|
|
|
5
5
|
type PromoSubscriptionEmailProps,
|
|
6
6
|
} from "./templates/PromoSubscriptionEmail.js";
|
|
7
7
|
import { GrantCreditsEmail, type GrantCreditsEmailProps } from "./templates/GrantCreditsEmail.js";
|
|
8
|
+
import { WelcomeEmail, type WelcomeEmailProps } from "./templates/WelcomeEmail.js";
|
|
8
9
|
|
|
9
10
|
// Re-export types
|
|
10
|
-
export type { OtpEmailProps, PromoSubscriptionEmailProps, GrantCreditsEmailProps };
|
|
11
|
+
export type { OtpEmailProps, PromoSubscriptionEmailProps, GrantCreditsEmailProps, WelcomeEmailProps };
|
|
11
12
|
|
|
12
13
|
// Re-export components for preview
|
|
13
|
-
export { OtpEmail, PromoSubscriptionEmail, GrantCreditsEmail };
|
|
14
|
+
export { OtpEmail, PromoSubscriptionEmail, GrantCreditsEmail, WelcomeEmail };
|
|
14
15
|
|
|
15
16
|
// Render functions
|
|
16
17
|
export interface RenderResult {
|
|
@@ -55,3 +56,16 @@ export async function renderGrantCreditsEmail(
|
|
|
55
56
|
text,
|
|
56
57
|
};
|
|
57
58
|
}
|
|
59
|
+
|
|
60
|
+
export async function renderWelcomeEmail(
|
|
61
|
+
props: WelcomeEmailProps
|
|
62
|
+
): Promise<RenderResult> {
|
|
63
|
+
const html = await render(WelcomeEmail(props));
|
|
64
|
+
const text = await render(WelcomeEmail(props), { plainText: true });
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
subject: "Welcome to Modelfy!",
|
|
68
|
+
html,
|
|
69
|
+
text,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -8,8 +8,9 @@ import {
|
|
|
8
8
|
Link,
|
|
9
9
|
Preview,
|
|
10
10
|
Font,
|
|
11
|
+
Img,
|
|
12
|
+
Button as ReactEmailButton,
|
|
11
13
|
} from "@react-email/components";
|
|
12
|
-
import { Header, Footer, Button } from "../../shared/components/index.js";
|
|
13
14
|
import { modelfyConfig } from "../config.js";
|
|
14
15
|
|
|
15
16
|
export interface GrantCreditsEmailProps {
|
|
@@ -20,101 +21,187 @@ export interface GrantCreditsEmailProps {
|
|
|
20
21
|
description?: string;
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
// Design System Colors - Matching Modelfy Landing
|
|
25
|
+
const colors = {
|
|
26
|
+
background: "#0d0d0d",
|
|
27
|
+
cardBg: "#121212",
|
|
28
|
+
primary: "#0a8f5a",
|
|
29
|
+
white: "#f2f2f2",
|
|
30
|
+
textSecondary: "rgba(242, 242, 242, 0.7)",
|
|
31
|
+
textMuted: "#8c8c8c",
|
|
32
|
+
border: "#262626",
|
|
33
|
+
};
|
|
34
|
+
|
|
23
35
|
const styles = {
|
|
24
36
|
body: {
|
|
25
37
|
margin: 0,
|
|
26
38
|
padding: 0,
|
|
27
|
-
backgroundColor:
|
|
28
|
-
fontFamily: "'
|
|
39
|
+
backgroundColor: colors.background,
|
|
40
|
+
fontFamily: "'Inter', 'Segoe UI', Arial, sans-serif",
|
|
29
41
|
},
|
|
30
42
|
container: {
|
|
31
|
-
maxWidth: "
|
|
32
|
-
margin: "
|
|
33
|
-
backgroundColor:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
maxWidth: "600px",
|
|
44
|
+
margin: "0 auto",
|
|
45
|
+
backgroundColor: colors.background,
|
|
46
|
+
},
|
|
47
|
+
header: {
|
|
48
|
+
backgroundColor: colors.background,
|
|
49
|
+
padding: "40px 32px 24px",
|
|
50
|
+
textAlign: "center" as const,
|
|
51
|
+
},
|
|
52
|
+
logo: {
|
|
53
|
+
display: "block" as const,
|
|
54
|
+
margin: "0 auto",
|
|
55
|
+
},
|
|
56
|
+
heroSection: {
|
|
57
|
+
padding: "24px 32px 40px",
|
|
58
|
+
textAlign: "center" as const,
|
|
59
|
+
},
|
|
60
|
+
heroTagline: {
|
|
61
|
+
margin: "0 0 12px",
|
|
62
|
+
fontSize: "13px",
|
|
63
|
+
fontWeight: 600,
|
|
64
|
+
color: colors.primary,
|
|
65
|
+
letterSpacing: "2px",
|
|
66
|
+
textTransform: "uppercase" as const,
|
|
67
|
+
},
|
|
68
|
+
heroHeading: {
|
|
43
69
|
margin: "0 0 16px",
|
|
44
|
-
fontSize: "
|
|
70
|
+
fontSize: "28px",
|
|
45
71
|
fontWeight: 700,
|
|
46
|
-
color:
|
|
47
|
-
|
|
72
|
+
color: colors.white,
|
|
73
|
+
lineHeight: "1.3",
|
|
48
74
|
},
|
|
49
75
|
paragraph: {
|
|
50
|
-
margin: "0 0
|
|
76
|
+
margin: "0 0 28px",
|
|
51
77
|
fontSize: "16px",
|
|
52
78
|
lineHeight: "1.6",
|
|
53
|
-
color:
|
|
79
|
+
color: colors.textSecondary,
|
|
80
|
+
textAlign: "center" as const,
|
|
54
81
|
},
|
|
55
82
|
creditBox: {
|
|
56
|
-
backgroundColor: "rgba(
|
|
57
|
-
border:
|
|
83
|
+
backgroundColor: "rgba(10, 143, 90, 0.15)",
|
|
84
|
+
border: `1px solid rgba(10, 143, 90, 0.3)`,
|
|
58
85
|
borderRadius: "12px",
|
|
59
86
|
padding: "24px",
|
|
60
|
-
marginBottom: "
|
|
87
|
+
marginBottom: "28px",
|
|
61
88
|
textAlign: "center" as const,
|
|
62
89
|
},
|
|
63
90
|
creditAmount: {
|
|
64
91
|
fontSize: "48px",
|
|
65
92
|
fontWeight: 700,
|
|
66
|
-
color:
|
|
67
|
-
margin: "0 0
|
|
93
|
+
color: colors.white,
|
|
94
|
+
margin: "0 0 4px",
|
|
68
95
|
},
|
|
69
96
|
creditLabel: {
|
|
70
|
-
fontSize: "
|
|
71
|
-
color:
|
|
97
|
+
fontSize: "14px",
|
|
98
|
+
color: colors.textMuted,
|
|
72
99
|
margin: 0,
|
|
73
100
|
},
|
|
74
101
|
detailsBox: {
|
|
75
|
-
backgroundColor:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
detailRow: {
|
|
81
|
-
display: "flex" as const,
|
|
82
|
-
justifyContent: "space-between" as const,
|
|
83
|
-
marginBottom: "8px",
|
|
102
|
+
backgroundColor: colors.cardBg,
|
|
103
|
+
border: `1px solid ${colors.border}`,
|
|
104
|
+
borderRadius: "12px",
|
|
105
|
+
padding: "20px 24px",
|
|
106
|
+
marginBottom: "28px",
|
|
84
107
|
},
|
|
85
108
|
detailLabel: {
|
|
86
|
-
fontSize: "
|
|
87
|
-
color:
|
|
88
|
-
margin: 0,
|
|
109
|
+
fontSize: "13px",
|
|
110
|
+
color: colors.textMuted,
|
|
111
|
+
margin: "0 0 4px",
|
|
89
112
|
},
|
|
90
113
|
detailValue: {
|
|
91
|
-
fontSize: "
|
|
114
|
+
fontSize: "16px",
|
|
92
115
|
fontWeight: 600,
|
|
93
|
-
color:
|
|
116
|
+
color: colors.white,
|
|
94
117
|
margin: 0,
|
|
95
118
|
},
|
|
96
119
|
buttonContainer: {
|
|
97
120
|
textAlign: "center" as const,
|
|
98
|
-
marginBottom: "
|
|
121
|
+
marginBottom: "28px",
|
|
122
|
+
},
|
|
123
|
+
ctaButton: {
|
|
124
|
+
display: "inline-block",
|
|
125
|
+
padding: "14px 36px",
|
|
126
|
+
fontSize: "15px",
|
|
127
|
+
fontWeight: 600,
|
|
128
|
+
textDecoration: "none",
|
|
129
|
+
borderRadius: "10px",
|
|
130
|
+
backgroundColor: colors.primary,
|
|
131
|
+
color: "#ffffff",
|
|
132
|
+
textAlign: "center" as const,
|
|
133
|
+
},
|
|
134
|
+
contentSection: {
|
|
135
|
+
backgroundColor: colors.cardBg,
|
|
136
|
+
padding: "32px",
|
|
137
|
+
borderTop: `1px solid ${colors.border}`,
|
|
99
138
|
},
|
|
100
139
|
smallText: {
|
|
101
140
|
margin: "0 0 12px",
|
|
102
141
|
fontSize: "14px",
|
|
103
142
|
lineHeight: "1.6",
|
|
104
|
-
color:
|
|
143
|
+
color: colors.textMuted,
|
|
144
|
+
textAlign: "center" as const,
|
|
145
|
+
},
|
|
146
|
+
descriptionText: {
|
|
147
|
+
margin: "0 0 24px",
|
|
148
|
+
fontSize: "15px",
|
|
149
|
+
lineHeight: "1.6",
|
|
150
|
+
color: colors.textSecondary,
|
|
151
|
+
textAlign: "center" as const,
|
|
152
|
+
fontStyle: "italic" as const,
|
|
105
153
|
},
|
|
106
154
|
link: {
|
|
107
|
-
color:
|
|
155
|
+
color: colors.primary,
|
|
108
156
|
textDecoration: "none",
|
|
109
157
|
fontWeight: 600,
|
|
110
158
|
},
|
|
159
|
+
footer: {
|
|
160
|
+
backgroundColor: colors.cardBg,
|
|
161
|
+
padding: "24px 32px",
|
|
162
|
+
textAlign: "center" as const,
|
|
163
|
+
borderTop: `1px solid ${colors.border}`,
|
|
164
|
+
},
|
|
165
|
+
footerLogo: {
|
|
166
|
+
display: "block" as const,
|
|
167
|
+
margin: "0 auto 12px",
|
|
168
|
+
opacity: 0.6,
|
|
169
|
+
},
|
|
170
|
+
footerText: {
|
|
171
|
+
margin: "0 0 4px",
|
|
172
|
+
fontSize: "11px",
|
|
173
|
+
color: colors.textMuted,
|
|
174
|
+
lineHeight: "1.6",
|
|
175
|
+
},
|
|
176
|
+
footerLink: {
|
|
177
|
+
color: colors.textMuted,
|
|
178
|
+
textDecoration: "underline",
|
|
179
|
+
},
|
|
180
|
+
downloadSection: {
|
|
181
|
+
backgroundColor: colors.cardBg,
|
|
182
|
+
padding: "24px 32px",
|
|
183
|
+
textAlign: "center" as const,
|
|
184
|
+
borderTop: `1px solid ${colors.border}`,
|
|
185
|
+
},
|
|
186
|
+
downloadText: {
|
|
187
|
+
margin: "0 0 16px",
|
|
188
|
+
fontSize: "14px",
|
|
189
|
+
color: colors.white,
|
|
190
|
+
},
|
|
191
|
+
badgeContainer: {
|
|
192
|
+
textAlign: "center" as const,
|
|
193
|
+
},
|
|
194
|
+
badge: {
|
|
195
|
+
display: "inline-block",
|
|
196
|
+
margin: "0 8px",
|
|
197
|
+
},
|
|
111
198
|
};
|
|
112
199
|
|
|
113
200
|
export function GrantCreditsEmail({
|
|
114
|
-
email,
|
|
201
|
+
email = "user@example.com",
|
|
115
202
|
credits,
|
|
116
|
-
durationDays,
|
|
117
|
-
expiresAt,
|
|
203
|
+
durationDays = 30,
|
|
204
|
+
expiresAt = "January 31, 2025",
|
|
118
205
|
description,
|
|
119
206
|
}: GrantCreditsEmailProps) {
|
|
120
207
|
const safeCredits = Number.isFinite(credits) ? Number(credits) : 0;
|
|
@@ -123,79 +210,139 @@ export function GrantCreditsEmail({
|
|
|
123
210
|
<Html lang="en">
|
|
124
211
|
<Head>
|
|
125
212
|
<Font
|
|
126
|
-
fontFamily="
|
|
213
|
+
fontFamily="Inter"
|
|
127
214
|
fallbackFontFamily="Arial"
|
|
128
215
|
webFont={{
|
|
129
|
-
url: "https://fonts.gstatic.com/s/
|
|
216
|
+
url: "https://fonts.gstatic.com/s/inter/v13/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hjp-Ek-_0.woff2",
|
|
130
217
|
format: "woff2",
|
|
131
218
|
}}
|
|
132
219
|
fontWeight={400}
|
|
133
220
|
fontStyle="normal"
|
|
134
221
|
/>
|
|
222
|
+
<Font
|
|
223
|
+
fontFamily="Inter"
|
|
224
|
+
fallbackFontFamily="Arial"
|
|
225
|
+
webFont={{
|
|
226
|
+
url: "https://fonts.gstatic.com/s/inter/v13/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuFuYAZ9hjp-Ek-_0.woff2",
|
|
227
|
+
format: "woff2",
|
|
228
|
+
}}
|
|
229
|
+
fontWeight={700}
|
|
230
|
+
fontStyle="normal"
|
|
231
|
+
/>
|
|
135
232
|
</Head>
|
|
136
233
|
<Preview>
|
|
137
234
|
You've received {safeCredits.toLocaleString()} credits on Modelfy!
|
|
138
235
|
</Preview>
|
|
139
236
|
<Body style={styles.body}>
|
|
140
237
|
<Container style={styles.container}>
|
|
141
|
-
|
|
142
|
-
<Section style={styles.
|
|
143
|
-
<
|
|
238
|
+
{/* Header */}
|
|
239
|
+
<Section style={styles.header}>
|
|
240
|
+
<Img
|
|
241
|
+
src={modelfyConfig.logoUrl}
|
|
242
|
+
width="130"
|
|
243
|
+
height="auto"
|
|
244
|
+
alt="Modelfy"
|
|
245
|
+
style={styles.logo}
|
|
246
|
+
/>
|
|
247
|
+
</Section>
|
|
248
|
+
|
|
249
|
+
{/* Hero Section */}
|
|
250
|
+
<Section style={styles.heroSection}>
|
|
251
|
+
<Text style={styles.heroTagline}>Bonus Credits</Text>
|
|
252
|
+
<Text style={styles.heroHeading}>Credits Added to Your Account!</Text>
|
|
144
253
|
<Text style={styles.paragraph}>
|
|
145
|
-
Hi <
|
|
254
|
+
Hi <span style={{ color: colors.white, fontWeight: 600 }}>{email}</span>, you've
|
|
255
|
+
received bonus credits to use on Modelfy.
|
|
146
256
|
</Text>
|
|
147
257
|
|
|
148
258
|
<div style={styles.creditBox}>
|
|
149
|
-
<Text style={styles.creditAmount}
|
|
259
|
+
<Text style={styles.creditAmount}>{safeCredits.toLocaleString()}</Text>
|
|
150
260
|
<Text style={styles.creditLabel}>credits</Text>
|
|
151
261
|
</div>
|
|
152
262
|
|
|
153
263
|
<div style={styles.detailsBox}>
|
|
154
264
|
<table width="100%" cellPadding={0} cellSpacing={0}>
|
|
155
|
-
<
|
|
156
|
-
<
|
|
157
|
-
<
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
<td style={{ textAlign: "right" }}>
|
|
168
|
-
<Text style={styles.detailValue}>{expiresAt}</Text>
|
|
169
|
-
</td>
|
|
170
|
-
</tr>
|
|
265
|
+
<tbody>
|
|
266
|
+
<tr>
|
|
267
|
+
<td style={{ paddingBottom: "16px" }}>
|
|
268
|
+
<Text style={styles.detailLabel}>Valid for</Text>
|
|
269
|
+
<Text style={styles.detailValue}>{durationDays} days</Text>
|
|
270
|
+
</td>
|
|
271
|
+
<td style={{ paddingBottom: "16px", textAlign: "right" as const }}>
|
|
272
|
+
<Text style={styles.detailLabel}>Expires</Text>
|
|
273
|
+
<Text style={styles.detailValue}>{expiresAt}</Text>
|
|
274
|
+
</td>
|
|
275
|
+
</tr>
|
|
276
|
+
</tbody>
|
|
171
277
|
</table>
|
|
172
278
|
</div>
|
|
173
279
|
|
|
174
|
-
{description &&
|
|
175
|
-
<Text style={styles.paragraph}>
|
|
176
|
-
<em>"{description}"</em>
|
|
177
|
-
</Text>
|
|
178
|
-
)}
|
|
280
|
+
{description && <Text style={styles.descriptionText}>"{description}"</Text>}
|
|
179
281
|
|
|
180
282
|
<div style={styles.buttonContainer}>
|
|
181
|
-
<
|
|
283
|
+
<ReactEmailButton href={modelfyConfig.appUrl} style={styles.ctaButton}>
|
|
284
|
+
Start Creating
|
|
285
|
+
</ReactEmailButton>
|
|
182
286
|
</div>
|
|
287
|
+
</Section>
|
|
183
288
|
|
|
289
|
+
{/* Content Section */}
|
|
290
|
+
<Section style={styles.contentSection}>
|
|
184
291
|
<Text style={styles.smallText}>
|
|
185
292
|
These credits will be used before your regular credits and expire on {expiresAt}.
|
|
186
293
|
</Text>
|
|
187
294
|
<Text style={styles.smallText}>
|
|
188
|
-
Questions?
|
|
295
|
+
Questions?{" "}
|
|
189
296
|
<Link href={`mailto:${modelfyConfig.supportEmail}`} style={styles.link}>
|
|
190
297
|
{modelfyConfig.supportEmail}
|
|
191
298
|
</Link>
|
|
192
299
|
</Text>
|
|
193
300
|
</Section>
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
301
|
+
|
|
302
|
+
{/* Download App Section */}
|
|
303
|
+
<Section style={styles.downloadSection}>
|
|
304
|
+
<Text style={styles.downloadText}>Get the Modelfy app</Text>
|
|
305
|
+
<div style={styles.badgeContainer}>
|
|
306
|
+
<Link href={modelfyConfig.appStoreUrl} style={styles.badge}>
|
|
307
|
+
<Img
|
|
308
|
+
src={modelfyConfig.appStoreBadgeUrl}
|
|
309
|
+
width="120"
|
|
310
|
+
height="40"
|
|
311
|
+
alt="Download on the App Store"
|
|
312
|
+
/>
|
|
313
|
+
</Link>
|
|
314
|
+
<Link href={modelfyConfig.playStoreUrl} style={styles.badge}>
|
|
315
|
+
<Img
|
|
316
|
+
src={modelfyConfig.playStoreBadgeUrl}
|
|
317
|
+
width="135"
|
|
318
|
+
height="40"
|
|
319
|
+
alt="Get it on Google Play"
|
|
320
|
+
/>
|
|
321
|
+
</Link>
|
|
322
|
+
</div>
|
|
323
|
+
</Section>
|
|
324
|
+
|
|
325
|
+
{/* Footer */}
|
|
326
|
+
<Section style={styles.footer}>
|
|
327
|
+
<Img
|
|
328
|
+
src={modelfyConfig.logoUrl}
|
|
329
|
+
width="80"
|
|
330
|
+
height="auto"
|
|
331
|
+
alt="Modelfy"
|
|
332
|
+
style={styles.footerLogo}
|
|
333
|
+
/>
|
|
334
|
+
<Text style={styles.footerText}>
|
|
335
|
+
© {new Date().getFullYear()} {modelfyConfig.companyName}. All rights reserved.
|
|
336
|
+
</Text>
|
|
337
|
+
<Text style={styles.footerText}>
|
|
338
|
+
You received this email because credits were added to your Modelfy account.
|
|
339
|
+
</Text>
|
|
340
|
+
<Text style={styles.footerText}>
|
|
341
|
+
<Link href={`${modelfyConfig.appUrl}/privacy`} style={styles.footerLink}>
|
|
342
|
+
Privacy Policy
|
|
343
|
+
</Link>
|
|
344
|
+
</Text>
|
|
345
|
+
</Section>
|
|
199
346
|
</Container>
|
|
200
347
|
</Body>
|
|
201
348
|
</Html>
|