@tracked/emails 0.1.4 → 0.2.0

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 (53) hide show
  1. package/dist/emails/client-onboarded.d.ts +35 -0
  2. package/dist/emails/client-onboarded.d.ts.map +1 -0
  3. package/dist/emails/client-onboarded.js +152 -0
  4. package/dist/emails/client-onboarded.js.map +1 -0
  5. package/dist/emails/index.d.ts +1 -0
  6. package/dist/emails/index.d.ts.map +1 -1
  7. package/dist/emails/index.js +1 -0
  8. package/dist/emails/index.js.map +1 -1
  9. package/dist/emails/monthly-report.d.ts.map +1 -1
  10. package/dist/emails/monthly-report.js +31 -47
  11. package/dist/emails/monthly-report.js.map +1 -1
  12. package/dist/index.d.ts +2 -2
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +2 -2
  15. package/dist/index.js.map +1 -1
  16. package/package.json +20 -20
  17. package/src/components/content.tsx +351 -0
  18. package/src/components/index.ts +44 -0
  19. package/src/components/interactive.tsx +260 -0
  20. package/src/components/layout.tsx +217 -0
  21. package/src/components/tokens.ts +74 -0
  22. package/src/components/typography.tsx +148 -0
  23. package/src/emails/anniversary.tsx +133 -0
  24. package/src/emails/app-review-request.tsx +100 -0
  25. package/src/emails/bodyweight-goal-reached.tsx +202 -350
  26. package/src/emails/client-inactive-alert.tsx +130 -0
  27. package/src/emails/client-onboarded.tsx +272 -0
  28. package/src/emails/coach-invite.tsx +67 -250
  29. package/src/emails/coach-removed-client.tsx +36 -197
  30. package/src/emails/direct-message.tsx +69 -227
  31. package/src/emails/feature-discovery.tsx +82 -266
  32. package/src/emails/first-workout-assigned.tsx +52 -238
  33. package/src/emails/first-workout-completed.tsx +88 -294
  34. package/src/emails/inactive-reengagement.tsx +81 -0
  35. package/src/emails/index.tsx +1 -0
  36. package/src/emails/monthly-report.tsx +195 -525
  37. package/src/emails/new-follower.tsx +60 -238
  38. package/src/emails/nps-survey.tsx +149 -0
  39. package/src/emails/subscription-canceled.tsx +88 -294
  40. package/src/emails/support-email.tsx +33 -67
  41. package/src/emails/team-invite.tsx +47 -240
  42. package/src/emails/team-member-removed-email.tsx +23 -218
  43. package/src/emails/tracked-magic-link-activate.tsx +29 -237
  44. package/src/emails/tracked-magic-link.tsx +31 -251
  45. package/src/emails/week-one-checkin.tsx +108 -329
  46. package/src/emails/weekly-progress-digest.tsx +248 -0
  47. package/src/emails/welcome.tsx +58 -326
  48. package/src/index.ts +19 -2
  49. package/dist/emails/client-accepted-invitation.d.ts +0 -10
  50. package/dist/emails/client-accepted-invitation.d.ts.map +0 -1
  51. package/dist/emails/client-accepted-invitation.js +0 -99
  52. package/dist/emails/client-accepted-invitation.js.map +0 -1
  53. package/src/emails/client-accepted-invitation.tsx +0 -258
@@ -0,0 +1,248 @@
1
+ import * as React from "react";
2
+ import { Section, Text, Row, Column } from "@react-email/components";
3
+ import {
4
+ EmailLayout,
5
+ EmailHeader,
6
+ EmailFooter,
7
+ Heading,
8
+ Paragraph,
9
+ PrimaryButton,
10
+ DiscordButton,
11
+ colors,
12
+ spacing,
13
+ borderRadius,
14
+ } from "../components";
15
+
16
+ interface WeeklyProgressDigestEmailProps {
17
+ userName: string;
18
+ weekStartDate: string;
19
+ weekEndDate: string;
20
+ workoutsCompleted: number;
21
+ workoutsPlanned?: number;
22
+ totalVolume?: string;
23
+ volumeChange?: number;
24
+ personalRecords?: number;
25
+ streakDays?: number;
26
+ topExercises?: Array<{ name: string; volume: string }>;
27
+ appUrl: string;
28
+ websiteUrl?: string;
29
+ unsubscribeUrl?: string;
30
+ }
31
+
32
+ const StatCard = ({
33
+ label,
34
+ value,
35
+ subtext,
36
+ }: {
37
+ label: string;
38
+ value: string | number;
39
+ subtext?: string;
40
+ }) => (
41
+ <Column
42
+ style={{
43
+ backgroundColor: colors.surface,
44
+ padding: "16px",
45
+ borderRadius: borderRadius.md,
46
+ textAlign: "center" as const,
47
+ border: `1px solid ${colors.border}`,
48
+ }}
49
+ >
50
+ <Text
51
+ style={{
52
+ color: colors.textMuted,
53
+ fontSize: "12px",
54
+ textTransform: "uppercase" as const,
55
+ letterSpacing: "0.5px",
56
+ margin: "0 0 4px 0",
57
+ }}
58
+ >
59
+ {label}
60
+ </Text>
61
+ <Text
62
+ style={{
63
+ color: colors.textPrimary,
64
+ fontSize: "24px",
65
+ fontWeight: "bold",
66
+ margin: "0",
67
+ }}
68
+ >
69
+ {value}
70
+ </Text>
71
+ {subtext && (
72
+ <Text
73
+ style={{
74
+ color: colors.accent,
75
+ fontSize: "12px",
76
+ margin: "4px 0 0 0",
77
+ }}
78
+ >
79
+ {subtext}
80
+ </Text>
81
+ )}
82
+ </Column>
83
+ );
84
+
85
+ export const WeeklyProgressDigestEmail = ({
86
+ userName = "Alex",
87
+ weekStartDate = "Dec 9",
88
+ weekEndDate = "Dec 15",
89
+ workoutsCompleted = 5,
90
+ workoutsPlanned = 6,
91
+ totalVolume = "125,000 lbs",
92
+ volumeChange = 8,
93
+ personalRecords = 2,
94
+ streakDays = 12,
95
+ topExercises = [
96
+ { name: "Bench Press", volume: "15,200 lbs" },
97
+ { name: "Squat", volume: "22,500 lbs" },
98
+ { name: "Deadlift", volume: "18,000 lbs" },
99
+ ],
100
+ appUrl = "tracked://bodyweight",
101
+ websiteUrl = "https://tracked.gg",
102
+ unsubscribeUrl = "https://tracked.gg/unsubscribe",
103
+ }: WeeklyProgressDigestEmailProps) => {
104
+ const completionRate = workoutsPlanned
105
+ ? Math.round((workoutsCompleted / workoutsPlanned) * 100)
106
+ : null;
107
+
108
+ const volumeChangeText =
109
+ volumeChange !== undefined
110
+ ? volumeChange > 0
111
+ ? `+${volumeChange}% vs last week`
112
+ : volumeChange < 0
113
+ ? `${volumeChange}% vs last week`
114
+ : "Same as last week"
115
+ : undefined;
116
+
117
+ return (
118
+ <EmailLayout preview={`Your weekly training summary - ${weekStartDate} to ${weekEndDate}`}>
119
+ <EmailHeader />
120
+
121
+ <Heading>Your Week in Review</Heading>
122
+ <Paragraph>
123
+ Hi {userName}, here's your training summary for {weekStartDate} -{" "}
124
+ {weekEndDate}.
125
+ </Paragraph>
126
+
127
+ {/* Stats Row */}
128
+ <Section style={{ margin: `${spacing.lg} 0` }}>
129
+ <Row>
130
+ <StatCard
131
+ label="Workouts"
132
+ value={workoutsCompleted}
133
+ subtext={completionRate ? `${completionRate}% complete` : undefined}
134
+ />
135
+ <Column style={{ width: "12px" }} />
136
+ <StatCard
137
+ label="Volume"
138
+ value={totalVolume || "-"}
139
+ subtext={volumeChangeText}
140
+ />
141
+ {personalRecords !== undefined && personalRecords > 0 && (
142
+ <>
143
+ <Column style={{ width: "12px" }} />
144
+ <StatCard label="New PRs" value={personalRecords} />
145
+ </>
146
+ )}
147
+ </Row>
148
+ </Section>
149
+
150
+ {/* Streak */}
151
+ {streakDays !== undefined && streakDays > 0 && (
152
+ <Section
153
+ style={{
154
+ backgroundColor: colors.surface,
155
+ padding: spacing.md,
156
+ borderRadius: borderRadius.md,
157
+ margin: `${spacing.md} 0`,
158
+ border: `1px solid ${colors.borderAccent}`,
159
+ textAlign: "center" as const,
160
+ }}
161
+ >
162
+ <Text
163
+ style={{
164
+ color: colors.accent,
165
+ fontSize: "14px",
166
+ fontWeight: "bold",
167
+ margin: "0",
168
+ }}
169
+ >
170
+ {streakDays} Day Streak!
171
+ </Text>
172
+ <Text
173
+ style={{
174
+ color: colors.textSecondary,
175
+ fontSize: "13px",
176
+ margin: "4px 0 0 0",
177
+ }}
178
+ >
179
+ Keep it going - consistency is key
180
+ </Text>
181
+ </Section>
182
+ )}
183
+
184
+ {/* Top Exercises */}
185
+ {topExercises && topExercises.length > 0 && (
186
+ <Section style={{ margin: `${spacing.lg} 0` }}>
187
+ <Text
188
+ style={{
189
+ color: colors.textPrimary,
190
+ fontSize: "14px",
191
+ fontWeight: "bold",
192
+ marginBottom: spacing.sm,
193
+ }}
194
+ >
195
+ Top Exercises This Week
196
+ </Text>
197
+ {topExercises.map((exercise, index) => (
198
+ <Row
199
+ key={index}
200
+ style={{
201
+ padding: "8px 0",
202
+ borderBottom:
203
+ index < topExercises.length - 1
204
+ ? `1px solid ${colors.border}`
205
+ : "none",
206
+ }}
207
+ >
208
+ <Column>
209
+ <Text
210
+ style={{
211
+ color: colors.textPrimary,
212
+ fontSize: "14px",
213
+ margin: "0",
214
+ }}
215
+ >
216
+ {exercise.name}
217
+ </Text>
218
+ </Column>
219
+ <Column style={{ textAlign: "right" as const }}>
220
+ <Text
221
+ style={{
222
+ color: colors.textSecondary,
223
+ fontSize: "14px",
224
+ margin: "0",
225
+ }}
226
+ >
227
+ {exercise.volume}
228
+ </Text>
229
+ </Column>
230
+ </Row>
231
+ ))}
232
+ </Section>
233
+ )}
234
+
235
+ <PrimaryButton href={appUrl}>View Full Report</PrimaryButton>
236
+
237
+ <Paragraph muted style={{ textAlign: "center" as const }}>
238
+ Keep pushing - every workout brings you closer to your goals.
239
+ </Paragraph>
240
+
241
+ <DiscordButton />
242
+
243
+ <EmailFooter websiteUrl={websiteUrl} marketing unsubscribeUrl={unsubscribeUrl} />
244
+ </EmailLayout>
245
+ );
246
+ };
247
+
248
+ export default WeeklyProgressDigestEmail;
@@ -1,341 +1,73 @@
1
- import React from "react";
1
+ import * as React from "react";
2
2
  import {
3
- Body,
4
- Button,
5
- Column,
6
- Container,
7
- Head,
8
- Hr,
9
- Html,
10
- Img,
11
- Link,
12
- Preview,
13
- Row,
14
- Section,
15
- Text,
16
- } from "@react-email/components";
3
+ EmailLayout,
4
+ EmailHeader,
5
+ EmailFooter,
6
+ Heading,
7
+ Paragraph,
8
+ FeatureBox,
9
+ FeatureList,
10
+ TipBox,
11
+ PrimaryButton,
12
+ DiscordButton,
13
+ } from "../components";
17
14
 
18
15
  interface WelcomeEmailProps {
19
16
  userName: string;
20
17
  appUrl: string;
21
- websiteUrl: string;
18
+ websiteUrl?: string;
19
+ unsubscribeUrl?: string;
22
20
  }
23
21
 
24
- const baseUrl = "https://tracked.gg/android-chrome-192x192.png";
25
-
26
22
  export const WelcomeEmail = ({
27
- userName,
28
- appUrl,
23
+ userName = "Alex",
24
+ appUrl = "tracked://app",
29
25
  websiteUrl = "https://tracked.gg",
26
+ unsubscribeUrl = "https://tracked.gg/unsubscribe",
30
27
  }: WelcomeEmailProps) => {
31
28
  return (
32
- <Html>
33
- <Head>
34
- <meta name="color-scheme" content="light only" />
35
- <meta name="supported-color-schemes" content="light only" />
36
- </Head>
37
- <Preview>Welcome to Tracked - Let's start your fitness journey!</Preview>
38
- <Body style={main}>
39
- <Container style={container}>
40
- <Section style={box}>
41
- <Row style={{ marginBottom: "8px" }}>
42
- <Column style={{ width: "auto", verticalAlign: "middle" }}>
43
- <Img src={`${baseUrl}`} width="28" height="28" alt="Tracked" />
44
- </Column>
45
- <Column
46
- style={{
47
- width: "auto",
48
- verticalAlign: "middle",
49
- paddingLeft: "4px",
50
- }}
51
- >
52
- <Text
53
- style={{
54
- fontSize: "28px",
55
- fontWeight: "900",
56
- fontFamily:
57
- "Raleway, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
58
- color: "#020617",
59
- margin: "0",
60
- lineHeight: "32px",
61
- letterSpacing: "0.5px",
62
- }}
63
- >
64
- TRACKED
65
- </Text>
66
- </Column>
67
- </Row>
68
- <Hr style={hr} />
69
-
70
- <Text style={heading}>Welcome to Tracked!</Text>
71
- <Text style={paragraph}>
72
- Hi {userName}, we're excited to have you join our community.
73
- Tracked is here to help you achieve your training goals with
74
- powerful tracking tools.
75
- </Text>
76
-
77
- <Section style={featureBox}>
78
- <Text style={featureHeading}>What you can do with Tracked:</Text>
79
- <ul style={featureList}>
80
- <li style={featureItem}>
81
- <strong>Track Workouts:</strong> Log your exercises, sets, and
82
- reps with the best tracking tools on the market.
83
- </li>
84
- <li style={featureItem}>
85
- <strong>Monitor Progress:</strong> Visualize your strength
86
- gains and workout history
87
- </li>
88
- <li style={featureItem}>
89
- <strong>Stay Accountable:</strong> Share your journey with the
90
- community
91
- </li>
92
- </ul>
93
- </Section>
94
-
95
- <div
96
- style={{
97
- marginTop: "24px",
98
- marginBottom: "24px",
99
- textAlign: "left" as const,
100
- }}
101
- >
102
- <a
103
- href={appUrl}
104
- style={{
105
- backgroundColor: "#0f172a",
106
- borderRadius: "8px",
107
- fontSize: "16px",
108
- fontWeight: "bold",
109
- textDecoration: "none",
110
- padding: "12px 32px",
111
- display: "inline-block",
112
- }}
113
- >
114
- <span style={{ color: "#ffffff", textDecoration: "none" }}>
115
- Open the App
116
- </span>
117
- </a>
118
- </div>
119
-
120
- <Section style={tipBox}>
121
- <Text style={tipHeading}>Tip:</Text>
122
- <Text style={tipText}>
123
- Consistency is key to seeing results, and we make it easy to
124
- track your progress every step of the way. Try your best to STAY
125
- IN THE GREEN!
126
- </Text>
127
- </Section>
128
-
129
- <Row style={row}>
130
- <Column style={column}>
131
- <Button
132
- style={appButton}
133
- href="https://apps.apple.com/app/tracked-training/id6450913418"
134
- >
135
- <Img
136
- src="https://cdn.trckd.ca/assets/app-store-black.png"
137
- alt="Download on the App Store"
138
- style={img}
139
- />
140
- </Button>
141
- </Column>
142
- <Column style={column}>
143
- <Button
144
- style={appButton}
145
- href="https://play.google.com/store/apps/details?id=com.tracked.mobile"
146
- >
147
- <Img
148
- src="https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png"
149
- alt="Google Play"
150
- style={img}
151
- />
152
- </Button>
153
- </Column>
154
- </Row>
155
-
156
- <div
157
- style={{
158
- textAlign: "left" as const,
159
- margin: "24px 0",
160
- }}
161
- >
162
- <a
163
- href="https://www.discord.gg/trackedgg"
164
- style={{
165
- backgroundColor: "#5865F2",
166
- borderRadius: "8px",
167
- fontSize: "16px",
168
- fontWeight: "bold",
169
- textDecoration: "none",
170
- padding: "12px 32px",
171
- display: "inline-block",
172
- }}
173
- >
174
- <span style={{ color: "#ffffff", textDecoration: "none" }}>
175
- Join our Discord Community
176
- </span>
177
- </a>
178
- </div>
179
-
180
- <Hr style={hr} />
181
- <Text style={footer}>
182
- Copyright © Tracked Training Platform Inc. <br /> 9101 Horne
183
- Street, Vancouver, BC
184
- </Text>
185
-
186
- <Container>
187
- <Link
188
- href={`${websiteUrl}/terms`}
189
- style={{ ...footer, paddingRight: 10 }}
190
- >
191
- Terms
192
- </Link>
193
- <Link style={{ ...footer, paddingRight: 10 }}> | </Link>
194
- <Link
195
- href={`${websiteUrl}/privacy`}
196
- style={{ ...footer, paddingRight: 10 }}
197
- >
198
- Privacy
199
- </Link>
200
- <Link style={{ ...footer, paddingRight: 10 }}> | </Link>
201
- <Link
202
- href={`${websiteUrl}/support`}
203
- style={{ ...footer, paddingRight: 10 }}
204
- >
205
- Support
206
- </Link>
207
- </Container>
208
-
209
- <Text style={footer}>
210
- This is a service notification by the Tracked Training Platform.
211
- </Text>
212
- </Section>
213
- </Container>
214
- </Body>
215
- </Html>
29
+ <EmailLayout preview="Welcome to Tracked - Let's start your fitness journey!">
30
+ <EmailHeader />
31
+
32
+ <Heading>Welcome to Tracked!</Heading>
33
+ <Paragraph>
34
+ Hi {userName}, we're excited to have you join our community. Tracked is
35
+ here to help you achieve your training goals with powerful tracking
36
+ tools.
37
+ </Paragraph>
38
+
39
+ <FeatureBox title="What you can do with Tracked:">
40
+ <FeatureList
41
+ items={[
42
+ {
43
+ title: "Track Workouts",
44
+ description:
45
+ "Log your exercises, sets, and reps with the best tracking tools on the market.",
46
+ },
47
+ {
48
+ title: "Monitor Progress",
49
+ description: "Visualize your strength gains and workout history",
50
+ },
51
+ {
52
+ title: "Stay Accountable",
53
+ description: "Share your journey with the community",
54
+ },
55
+ ]}
56
+ />
57
+ </FeatureBox>
58
+
59
+ <PrimaryButton href={appUrl}>Open the App</PrimaryButton>
60
+
61
+ <TipBox>
62
+ Consistency is key to seeing results, and we make it easy to track your
63
+ progress every step of the way. Try your best to STAY IN THE GREEN!
64
+ </TipBox>
65
+
66
+ <DiscordButton />
67
+
68
+ <EmailFooter websiteUrl={websiteUrl} marketing unsubscribeUrl={unsubscribeUrl} />
69
+ </EmailLayout>
216
70
  );
217
71
  };
218
72
 
219
- const main = {
220
- backgroundColor: "#020617", // slate-950
221
- fontFamily:
222
- '-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
223
- };
224
-
225
- const container = {
226
- backgroundColor: "#020617", // slate-950
227
- margin: "0 auto",
228
- padding: "20px 0 48px",
229
- marginBottom: "64px",
230
- borderRadius: "8px",
231
- };
232
-
233
- const box = {
234
- padding: "0 24px",
235
- };
236
-
237
- const hr = {
238
- borderColor: "#4ade80", // green-400
239
- margin: "24px 0",
240
- borderWidth: "1px",
241
- };
242
-
243
- const paragraph = {
244
- color: "#ffffff", // white
245
- fontSize: "16px",
246
- lineHeight: "24px",
247
- textAlign: "left" as const,
248
- };
249
-
250
- const heading = {
251
- color: "#ffffff", // white
252
- fontSize: "24px",
253
- lineHeight: "32px",
254
- fontWeight: "bold",
255
- marginBottom: "16px",
256
- };
257
-
258
- const featureBox = {
259
- backgroundColor: "#1e293b",
260
- padding: "16px 24px",
261
- borderRadius: "8px",
262
- margin: "24px 0",
263
- };
264
-
265
- const featureHeading = {
266
- color: "#ffffff",
267
- fontSize: "16px",
268
- fontWeight: "bold",
269
- marginBottom: "12px",
270
- };
271
-
272
- const featureList = {
273
- margin: "0",
274
- paddingLeft: "20px",
275
- };
276
-
277
- const featureItem = {
278
- color: "#e2e8f0",
279
- fontSize: "14px",
280
- lineHeight: "24px",
281
- marginBottom: "8px",
282
- };
283
-
284
- const tipBox = {
285
- backgroundColor: "#1e293b",
286
- padding: "16px 24px",
287
- borderRadius: "8px",
288
- margin: "24px 0",
289
- borderLeft: "4px solid #4ade80",
290
- };
291
-
292
- const tipHeading = {
293
- color: "#4ade80",
294
- fontSize: "14px",
295
- fontWeight: "bold",
296
- };
297
-
298
- const tipText = {
299
- color: "#e2e8f0",
300
- fontSize: "14px",
301
- lineHeight: "20px",
302
- };
303
-
304
- const row = {
305
- display: "flex",
306
- flexDirection: "row" as const,
307
- };
308
-
309
- const column = {
310
- flex: "0 0 48%",
311
- "@media (maxWidth: 600px)": {
312
- flex: "0 0 100%",
313
- marginBottom: "10px",
314
- },
315
- };
316
-
317
- const img = {
318
- maxWidth: "100%",
319
- height: "auto",
320
- };
321
-
322
- const appButton = {
323
- backgroundColor: "transparent",
324
- borderRadius: "8px",
325
- color: "#ffffff", // white
326
- fontSize: "16px",
327
- fontWeight: "bold",
328
- textDecoration: "none",
329
- textAlign: "center" as const,
330
- display: "block",
331
- width: "100%",
332
- maxWidth: "150px",
333
- };
334
-
335
- const footer = {
336
- color: "#94a3b8", // slate-400 for subtle footer text
337
- fontSize: "12px",
338
- lineHeight: "16px",
339
- };
340
-
341
73
  export default WelcomeEmail;