brookmind-emails 0.1.10 → 0.1.12

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