@tracked/emails 0.1.5 → 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 (50) 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/index.d.ts +2 -2
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -2
  12. package/dist/index.js.map +1 -1
  13. package/package.json +20 -20
  14. package/src/components/content.tsx +351 -0
  15. package/src/components/index.ts +44 -0
  16. package/src/components/interactive.tsx +260 -0
  17. package/src/components/layout.tsx +217 -0
  18. package/src/components/tokens.ts +74 -0
  19. package/src/components/typography.tsx +148 -0
  20. package/src/emails/anniversary.tsx +133 -0
  21. package/src/emails/app-review-request.tsx +100 -0
  22. package/src/emails/bodyweight-goal-reached.tsx +202 -350
  23. package/src/emails/client-inactive-alert.tsx +130 -0
  24. package/src/emails/client-onboarded.tsx +272 -0
  25. package/src/emails/coach-invite.tsx +67 -250
  26. package/src/emails/coach-removed-client.tsx +36 -197
  27. package/src/emails/direct-message.tsx +69 -227
  28. package/src/emails/feature-discovery.tsx +82 -266
  29. package/src/emails/first-workout-assigned.tsx +52 -238
  30. package/src/emails/first-workout-completed.tsx +88 -294
  31. package/src/emails/inactive-reengagement.tsx +81 -0
  32. package/src/emails/index.tsx +1 -0
  33. package/src/emails/monthly-report.tsx +198 -520
  34. package/src/emails/new-follower.tsx +60 -238
  35. package/src/emails/nps-survey.tsx +149 -0
  36. package/src/emails/subscription-canceled.tsx +88 -294
  37. package/src/emails/support-email.tsx +33 -67
  38. package/src/emails/team-invite.tsx +47 -240
  39. package/src/emails/team-member-removed-email.tsx +23 -218
  40. package/src/emails/tracked-magic-link-activate.tsx +29 -237
  41. package/src/emails/tracked-magic-link.tsx +31 -251
  42. package/src/emails/week-one-checkin.tsx +108 -329
  43. package/src/emails/weekly-progress-digest.tsx +248 -0
  44. package/src/emails/welcome.tsx +58 -326
  45. package/src/index.ts +19 -2
  46. package/dist/emails/client-accepted-invitation.d.ts +0 -10
  47. package/dist/emails/client-accepted-invitation.d.ts.map +0 -1
  48. package/dist/emails/client-accepted-invitation.js +0 -99
  49. package/dist/emails/client-accepted-invitation.js.map +0 -1
  50. package/src/emails/client-accepted-invitation.tsx +0 -258
@@ -0,0 +1,217 @@
1
+ import * as React from "react";
2
+ import {
3
+ Body,
4
+ Container,
5
+ Head,
6
+ Hr,
7
+ Html,
8
+ Img,
9
+ Link,
10
+ Preview,
11
+ Section,
12
+ Text,
13
+ } from "@react-email/components";
14
+ import { colors, typography, spacing } from "./tokens";
15
+ import { AppStoreButtons } from "./interactive";
16
+
17
+ const baseUrl = "https://tracked.gg/android-chrome-192x192.png";
18
+ const defaultWebsiteUrl = "https://tracked.gg";
19
+
20
+ // ============================================
21
+ // EmailLayout - Main wrapper component
22
+ // ============================================
23
+ interface EmailLayoutProps {
24
+ preview: string;
25
+ children: React.ReactNode;
26
+ }
27
+
28
+ export const EmailLayout = ({ preview, children }: EmailLayoutProps) => {
29
+ return (
30
+ <Html>
31
+ <Head>
32
+ <meta name="color-scheme" content="light only" />
33
+ <meta name="supported-color-schemes" content="light only" />
34
+ </Head>
35
+ <Preview>{preview}</Preview>
36
+ <Body style={mainStyle}>
37
+ <Container style={containerStyle}>
38
+ <Section style={boxStyle}>{children}</Section>
39
+ </Container>
40
+ </Body>
41
+ </Html>
42
+ );
43
+ };
44
+
45
+ const mainStyle = {
46
+ backgroundColor: colors.background,
47
+ fontFamily: typography.fontFamily,
48
+ };
49
+
50
+ const containerStyle = {
51
+ backgroundColor: colors.background,
52
+ margin: "0 auto",
53
+ padding: "20px 0 48px",
54
+ maxWidth: "600px",
55
+ };
56
+
57
+ const boxStyle = {
58
+ padding: "0 24px",
59
+ };
60
+
61
+ // ============================================
62
+ // EmailHeader - Logo and brand name
63
+ // ============================================
64
+ interface EmailHeaderProps {
65
+ showDivider?: boolean;
66
+ }
67
+
68
+ export const EmailHeader = ({ showDivider = true }: EmailHeaderProps) => {
69
+ return (
70
+ <>
71
+ <table cellPadding="0" cellSpacing="0" style={{ marginBottom: spacing.sm }}>
72
+ <tr>
73
+ <td style={{ verticalAlign: "middle" }}>
74
+ <Img src={baseUrl} width="28" height="28" alt="Tracked" />
75
+ </td>
76
+ <td style={{ verticalAlign: "middle", paddingLeft: "6px" }}>
77
+ <Text style={logoStyle}>TRACKED</Text>
78
+ </td>
79
+ </tr>
80
+ </table>
81
+ {showDivider && <Hr style={headerDividerStyle} />}
82
+ </>
83
+ );
84
+ };
85
+
86
+ const logoStyle = {
87
+ fontSize: "28px",
88
+ fontWeight: "900" as const,
89
+ fontFamily: typography.brandFont,
90
+ color: colors.textPrimary,
91
+ margin: "0",
92
+ lineHeight: "32px",
93
+ letterSpacing: "-0.5px",
94
+ };
95
+
96
+ const headerDividerStyle = {
97
+ borderColor: colors.border,
98
+ margin: `${spacing.lg} 0`,
99
+ borderWidth: "1px",
100
+ };
101
+
102
+ // ============================================
103
+ // EmailFooter - Copyright and links
104
+ // ============================================
105
+ interface EmailFooterProps {
106
+ websiteUrl?: string;
107
+ marketing?: boolean;
108
+ unsubscribeUrl?: string;
109
+ }
110
+
111
+ export const EmailFooter = ({
112
+ websiteUrl = defaultWebsiteUrl,
113
+ marketing = false,
114
+ unsubscribeUrl,
115
+ }: EmailFooterProps) => {
116
+ return (
117
+ <>
118
+ <Hr style={footerDividerStyle} />
119
+ <AppStoreButtons />
120
+ <Text style={footerTextStyle}>
121
+ Copyright © {new Date().getFullYear()} Tracked Training Platform Inc.{" "}
122
+ <br />
123
+ 9101 Horne Street, Vancouver, BC
124
+ </Text>
125
+ <Section style={{ textAlign: "center" as const }}>
126
+ <Link href={`${websiteUrl}/terms`} style={footerLinkStyle}>
127
+ Terms
128
+ </Link>
129
+ <Text style={footerDividerTextStyle}> | </Text>
130
+ <Link href={`${websiteUrl}/privacy`} style={footerLinkStyle}>
131
+ Privacy
132
+ </Link>
133
+ <Text style={footerDividerTextStyle}> | </Text>
134
+ <Link href={`${websiteUrl}/support`} style={footerLinkStyle}>
135
+ Support
136
+ </Link>
137
+ {marketing && unsubscribeUrl && (
138
+ <>
139
+ <Text style={footerDividerTextStyle}> | </Text>
140
+ <Link href={unsubscribeUrl} style={footerLinkStyle}>
141
+ Unsubscribe
142
+ </Link>
143
+ </>
144
+ )}
145
+ </Section>
146
+ <Text style={footerDisclaimerStyle}>
147
+ {marketing
148
+ ? "You're receiving this email because you opted in to marketing communications from Tracked."
149
+ : "This is a service notification by the Tracked Training Platform."}
150
+ </Text>
151
+ </>
152
+ );
153
+ };
154
+
155
+ const footerDividerStyle = {
156
+ borderColor: colors.border,
157
+ margin: `${spacing.lg} 0`,
158
+ borderWidth: "1px",
159
+ };
160
+
161
+ const footerTextStyle = {
162
+ color: colors.textMuted,
163
+ fontSize: "12px",
164
+ lineHeight: "16px",
165
+ textAlign: "center" as const,
166
+ };
167
+
168
+ const footerLinkStyle = {
169
+ color: colors.textMuted,
170
+ fontSize: "12px",
171
+ textDecoration: "none",
172
+ };
173
+
174
+ const footerDividerTextStyle = {
175
+ color: colors.textMuted,
176
+ fontSize: "12px",
177
+ display: "inline" as const,
178
+ };
179
+
180
+ const footerDisclaimerStyle = {
181
+ color: colors.textMuted,
182
+ fontSize: "12px",
183
+ lineHeight: "16px",
184
+ textAlign: "center" as const,
185
+ marginTop: spacing.md,
186
+ };
187
+
188
+ // ============================================
189
+ // ContentSection - Padded content wrapper
190
+ // ============================================
191
+ interface ContentSectionProps {
192
+ children: React.ReactNode;
193
+ style?: React.CSSProperties;
194
+ }
195
+
196
+ export const ContentSection = ({ children, style }: ContentSectionProps) => {
197
+ return <Section style={{ marginBottom: spacing.lg, ...style }}>{children}</Section>;
198
+ };
199
+
200
+ // ============================================
201
+ // Divider - Horizontal rule
202
+ // ============================================
203
+ interface DividerProps {
204
+ accent?: boolean;
205
+ }
206
+
207
+ export const Divider = ({ accent = false }: DividerProps) => {
208
+ return (
209
+ <Hr
210
+ style={{
211
+ borderColor: accent ? colors.borderAccent : colors.border,
212
+ margin: `${spacing.lg} 0`,
213
+ borderWidth: "1px",
214
+ }}
215
+ />
216
+ );
217
+ };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Design tokens for email templates
3
+ * Light/professional theme
4
+ */
5
+
6
+ export const colors = {
7
+ // Backgrounds
8
+ background: "#ffffff",
9
+ surface: "#f8fafc", // slate-50
10
+ surfaceAlt: "#f1f5f9", // slate-100
11
+
12
+ // Text
13
+ textPrimary: "#0f172a", // slate-900
14
+ textSecondary: "#475569", // slate-600
15
+ textMuted: "#94a3b8", // slate-400
16
+
17
+ // Brand
18
+ primary: "#0f172a", // dark navy for buttons
19
+ accent: "#10b981", // emerald-500 for highlights
20
+ discord: "#5865F2",
21
+ youtube: "#FF0000",
22
+ tiktok: "#000000",
23
+ instagram: "#E4405F",
24
+
25
+ // Borders
26
+ border: "#e2e8f0", // slate-200
27
+ borderStrong: "#cbd5e1", // slate-300
28
+ borderAccent: "#10b981", // emerald-500
29
+
30
+ // Status
31
+ success: "#10b981", // emerald-500
32
+ error: "#ef4444", // red-500
33
+ warning: "#f59e0b", // amber-500
34
+ };
35
+
36
+ export const typography = {
37
+ fontFamily:
38
+ '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif',
39
+ brandFont:
40
+ 'Raleway, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
41
+ };
42
+
43
+ export const spacing = {
44
+ xs: "4px",
45
+ sm: "8px",
46
+ md: "16px",
47
+ lg: "24px",
48
+ xl: "32px",
49
+ xxl: "48px",
50
+ };
51
+
52
+ export const borderRadius = {
53
+ sm: "4px",
54
+ md: "8px",
55
+ lg: "12px",
56
+ full: "9999px",
57
+ };
58
+
59
+ // Base styles used across components
60
+ export const baseStyles = {
61
+ main: {
62
+ backgroundColor: colors.background,
63
+ fontFamily: typography.fontFamily,
64
+ },
65
+ container: {
66
+ backgroundColor: colors.background,
67
+ margin: "0 auto",
68
+ padding: "20px 0 48px",
69
+ maxWidth: "600px",
70
+ },
71
+ box: {
72
+ padding: "0 24px",
73
+ },
74
+ };
@@ -0,0 +1,148 @@
1
+ import * as React from "react";
2
+ import { Text, Heading as EmailHeading } from "@react-email/components";
3
+ import { colors, spacing } from "./tokens";
4
+
5
+ // ============================================
6
+ // Heading - Title text with variants
7
+ // ============================================
8
+ interface HeadingProps {
9
+ children: React.ReactNode;
10
+ as?: "h1" | "h2" | "h3";
11
+ style?: React.CSSProperties;
12
+ }
13
+
14
+ export const Heading = ({ children, as = "h1", style }: HeadingProps) => {
15
+ const baseStyle = headingStyles[as];
16
+ return (
17
+ <EmailHeading as={as} style={{ ...baseStyle, ...style }}>
18
+ {children}
19
+ </EmailHeading>
20
+ );
21
+ };
22
+
23
+ const headingStyles = {
24
+ h1: {
25
+ color: colors.textPrimary,
26
+ fontSize: "24px",
27
+ lineHeight: "32px",
28
+ fontWeight: "bold" as const,
29
+ marginBottom: spacing.md,
30
+ marginTop: "0",
31
+ },
32
+ h2: {
33
+ color: colors.textPrimary,
34
+ fontSize: "20px",
35
+ lineHeight: "28px",
36
+ fontWeight: "600" as const,
37
+ marginBottom: spacing.sm,
38
+ marginTop: "0",
39
+ },
40
+ h3: {
41
+ color: colors.textPrimary,
42
+ fontSize: "16px",
43
+ lineHeight: "24px",
44
+ fontWeight: "600" as const,
45
+ marginBottom: spacing.sm,
46
+ marginTop: "0",
47
+ },
48
+ };
49
+
50
+ // ============================================
51
+ // Paragraph - Standard body text
52
+ // ============================================
53
+ interface ParagraphProps {
54
+ children: React.ReactNode;
55
+ muted?: boolean;
56
+ style?: React.CSSProperties;
57
+ }
58
+
59
+ export const Paragraph = ({ children, muted = false, style }: ParagraphProps) => {
60
+ return (
61
+ <Text
62
+ style={{
63
+ color: muted ? colors.textSecondary : colors.textPrimary,
64
+ fontSize: "16px",
65
+ lineHeight: "24px",
66
+ textAlign: "left" as const,
67
+ margin: `0 0 ${spacing.md} 0`,
68
+ ...style,
69
+ }}
70
+ >
71
+ {children}
72
+ </Text>
73
+ );
74
+ };
75
+
76
+ // ============================================
77
+ // Label - Small muted text for labels
78
+ // ============================================
79
+ interface LabelProps {
80
+ children: React.ReactNode;
81
+ style?: React.CSSProperties;
82
+ }
83
+
84
+ export const Label = ({ children, style }: LabelProps) => {
85
+ return (
86
+ <Text
87
+ style={{
88
+ color: colors.textMuted,
89
+ fontSize: "14px",
90
+ lineHeight: "20px",
91
+ margin: "0",
92
+ ...style,
93
+ }}
94
+ >
95
+ {children}
96
+ </Text>
97
+ );
98
+ };
99
+
100
+ // ============================================
101
+ // HighlightText - Accent-colored text
102
+ // ============================================
103
+ interface HighlightTextProps {
104
+ children: React.ReactNode;
105
+ style?: React.CSSProperties;
106
+ }
107
+
108
+ export const HighlightText = ({ children, style }: HighlightTextProps) => {
109
+ return (
110
+ <Text
111
+ style={{
112
+ color: colors.accent,
113
+ fontSize: "16px",
114
+ fontWeight: "600" as const,
115
+ lineHeight: "24px",
116
+ margin: "0",
117
+ ...style,
118
+ }}
119
+ >
120
+ {children}
121
+ </Text>
122
+ );
123
+ };
124
+
125
+ // ============================================
126
+ // SmallText - Smaller body text
127
+ // ============================================
128
+ interface SmallTextProps {
129
+ children: React.ReactNode;
130
+ muted?: boolean;
131
+ style?: React.CSSProperties;
132
+ }
133
+
134
+ export const SmallText = ({ children, muted = false, style }: SmallTextProps) => {
135
+ return (
136
+ <Text
137
+ style={{
138
+ color: muted ? colors.textMuted : colors.textSecondary,
139
+ fontSize: "14px",
140
+ lineHeight: "20px",
141
+ margin: "0",
142
+ ...style,
143
+ }}
144
+ >
145
+ {children}
146
+ </Text>
147
+ );
148
+ };
@@ -0,0 +1,133 @@
1
+ import * as React from "react";
2
+ import { Section, Text } 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
+ } from "../components";
14
+
15
+ interface AnniversaryEmailProps {
16
+ userName: string;
17
+ yearsOnPlatform: number;
18
+ totalWorkouts?: number;
19
+ totalVolume?: string;
20
+ appUrl: string;
21
+ websiteUrl?: string;
22
+ unsubscribeUrl?: string;
23
+ }
24
+
25
+ export const AnniversaryEmail = ({
26
+ userName = "Alex",
27
+ yearsOnPlatform = 1,
28
+ totalWorkouts = 156,
29
+ totalVolume = "1,250,000 lbs",
30
+ appUrl = "tracked://bodyweight",
31
+ websiteUrl = "https://tracked.gg",
32
+ unsubscribeUrl = "https://tracked.gg/unsubscribe",
33
+ }: AnniversaryEmailProps) => {
34
+ const yearText = yearsOnPlatform === 1 ? "1 Year" : `${yearsOnPlatform} Years`;
35
+
36
+ return (
37
+ <EmailLayout preview={`Happy ${yearText} Anniversary on Tracked!`}>
38
+ <EmailHeader />
39
+
40
+ <Heading>Happy {yearText} Anniversary!</Heading>
41
+ <Paragraph>
42
+ Congratulations {userName}! Today marks {yearsOnPlatform}{" "}
43
+ {yearsOnPlatform === 1 ? "year" : "years"} since you joined Tracked.
44
+ Thank you for being part of our community!
45
+ </Paragraph>
46
+
47
+ {(totalWorkouts || totalVolume) && (
48
+ <Section
49
+ style={{
50
+ backgroundColor: colors.surface,
51
+ padding: spacing.lg,
52
+ borderRadius: "8px",
53
+ margin: `${spacing.lg} 0`,
54
+ border: `1px solid ${colors.border}`,
55
+ textAlign: "center" as const,
56
+ }}
57
+ >
58
+ <Text
59
+ style={{
60
+ color: colors.accent,
61
+ fontSize: "14px",
62
+ fontWeight: "bold",
63
+ textTransform: "uppercase" as const,
64
+ letterSpacing: "0.5px",
65
+ margin: "0 0 16px 0",
66
+ }}
67
+ >
68
+ Your Journey So Far
69
+ </Text>
70
+ {totalWorkouts && (
71
+ <Text
72
+ style={{
73
+ color: colors.textPrimary,
74
+ fontSize: "32px",
75
+ fontWeight: "bold",
76
+ margin: "0 0 4px 0",
77
+ }}
78
+ >
79
+ {totalWorkouts.toLocaleString()}
80
+ </Text>
81
+ )}
82
+ {totalWorkouts && (
83
+ <Text
84
+ style={{
85
+ color: colors.textSecondary,
86
+ fontSize: "14px",
87
+ margin: "0 0 16px 0",
88
+ }}
89
+ >
90
+ workouts logged
91
+ </Text>
92
+ )}
93
+ {totalVolume && (
94
+ <>
95
+ <Text
96
+ style={{
97
+ color: colors.textPrimary,
98
+ fontSize: "32px",
99
+ fontWeight: "bold",
100
+ margin: "0 0 4px 0",
101
+ }}
102
+ >
103
+ {totalVolume}
104
+ </Text>
105
+ <Text
106
+ style={{
107
+ color: colors.textSecondary,
108
+ fontSize: "14px",
109
+ margin: "0",
110
+ }}
111
+ >
112
+ total volume lifted
113
+ </Text>
114
+ </>
115
+ )}
116
+ </Section>
117
+ )}
118
+
119
+ <Paragraph>
120
+ Here's to another year of crushing goals and getting stronger. Keep up
121
+ the amazing work!
122
+ </Paragraph>
123
+
124
+ <PrimaryButton href={appUrl}>View Your Progress</PrimaryButton>
125
+
126
+ <DiscordButton />
127
+
128
+ <EmailFooter websiteUrl={websiteUrl} marketing unsubscribeUrl={unsubscribeUrl} />
129
+ </EmailLayout>
130
+ );
131
+ };
132
+
133
+ export default AnniversaryEmail;
@@ -0,0 +1,100 @@
1
+ import * as React from "react";
2
+ import { Section, Text } from "@react-email/components";
3
+ import {
4
+ EmailLayout,
5
+ EmailHeader,
6
+ EmailFooter,
7
+ Heading,
8
+ Paragraph,
9
+ PrimaryButton,
10
+ SecondaryButton,
11
+ DiscordButton,
12
+ colors,
13
+ spacing,
14
+ borderRadius,
15
+ } from "../components";
16
+
17
+ interface AppReviewRequestEmailProps {
18
+ userName: string;
19
+ workoutsCompleted: number;
20
+ appStoreUrl?: string;
21
+ playStoreUrl?: string;
22
+ websiteUrl?: string;
23
+ unsubscribeUrl?: string;
24
+ }
25
+
26
+ export const AppReviewRequestEmail = ({
27
+ userName = "Alex",
28
+ workoutsCompleted = 50,
29
+ appStoreUrl = "https://apps.apple.com/app/tracked-training/id6450913418",
30
+ playStoreUrl = "https://play.google.com/store/apps/details?id=com.tracked.mobile",
31
+ websiteUrl = "https://tracked.gg",
32
+ unsubscribeUrl = "https://tracked.gg/unsubscribe",
33
+ }: AppReviewRequestEmailProps) => {
34
+ return (
35
+ <EmailLayout preview={`You've completed ${workoutsCompleted} workouts! Share your experience`}>
36
+ <EmailHeader />
37
+
38
+ <Heading>You're Crushing It!</Heading>
39
+ <Paragraph>
40
+ Hi {userName}, you've completed <strong>{workoutsCompleted} workouts</strong> on
41
+ Tracked. That's an amazing achievement!
42
+ </Paragraph>
43
+
44
+ <Section
45
+ style={{
46
+ backgroundColor: colors.surface,
47
+ padding: spacing.lg,
48
+ borderRadius: borderRadius.md,
49
+ margin: `${spacing.lg} 0`,
50
+ border: `1px solid ${colors.border}`,
51
+ textAlign: "center" as const,
52
+ }}
53
+ >
54
+ <Text
55
+ style={{
56
+ color: colors.textPrimary,
57
+ fontSize: "48px",
58
+ fontWeight: "bold",
59
+ margin: "0",
60
+ }}
61
+ >
62
+ {workoutsCompleted}
63
+ </Text>
64
+ <Text
65
+ style={{
66
+ color: colors.textSecondary,
67
+ fontSize: "14px",
68
+ margin: "8px 0 0 0",
69
+ }}
70
+ >
71
+ workouts and counting
72
+ </Text>
73
+ </Section>
74
+
75
+ <Paragraph>
76
+ We'd love to hear what you think! A quick review helps other athletes
77
+ discover Tracked and helps us continue improving the app.
78
+ </Paragraph>
79
+
80
+ <Paragraph style={{ fontWeight: "600" }}>
81
+ Would you take 30 seconds to leave a review?
82
+ </Paragraph>
83
+
84
+ <PrimaryButton href={appStoreUrl}>Review on App Store</PrimaryButton>
85
+
86
+ <SecondaryButton href={playStoreUrl}>Review on Google Play</SecondaryButton>
87
+
88
+ <Paragraph muted style={{ textAlign: "center" as const }}>
89
+ Thank you for being part of the Tracked community. Your support means
90
+ everything to us!
91
+ </Paragraph>
92
+
93
+ <DiscordButton />
94
+
95
+ <EmailFooter websiteUrl={websiteUrl} marketing unsubscribeUrl={unsubscribeUrl} />
96
+ </EmailLayout>
97
+ );
98
+ };
99
+
100
+ export default AppReviewRequestEmail;