Skip to content

Commit 3aa5a9c

Browse files
committed
simplify email template dates with z.coerce.date()
1 parent 9514ebf commit 3aa5a9c

File tree

5 files changed

+20
-64
lines changed

5 files changed

+20
-64
lines changed

emails/emails/failed-bg-job.tsx

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,21 @@
11
import z from "zod";
22
import { Template } from "../templates/btrix.js";
3-
import { formatDateTime, parseDate } from "../lib/date.js";
4-
import {
5-
CodeInline,
6-
Column,
7-
Row,
8-
Section,
9-
Text,
10-
} from "@react-email/components";
3+
import { formatDateTime } from "../lib/date.js";
4+
import { CodeInline } from "@react-email/components";
115

126
export const schema = z.object({
137
org: z.string().optional(),
148
job: z.object({
159
id: z.string(),
1610
oid: z.string().optional(),
1711
type: z.string(),
18-
started: z.string(),
12+
started: z.coerce.date(),
1913
object_type: z.string().optional(),
2014
object_id: z.string().optional(),
2115
file_path: z.string().optional(),
2216
replica_storage: z.string().optional(),
2317
}),
24-
finished: z.string(),
18+
finished: z.coerce.date(),
2519
});
2620

2721
export type FailedBgJobEmailProps = z.infer<typeof schema>;
@@ -61,12 +55,8 @@ export const FailedBgJobEmail = ({
6155
linky={{ version: "concerned", caption: false }}
6256
>
6357
<table align="center" width="100%">
64-
<DataRow label="Started At">
65-
{formatDateTime(parseDate(job.started))}
66-
</DataRow>
67-
<DataRow label="Finished At">
68-
{formatDateTime(parseDate(finished))}
69-
</DataRow>
58+
<DataRow label="Started At">{formatDateTime(job.started)}</DataRow>
59+
<DataRow label="Finished At">{formatDateTime(finished)}</DataRow>
7060
{org && (
7161
<DataRow label="Organization">
7262
<Code>{org}</Code>
@@ -110,13 +100,13 @@ FailedBgJobEmail.PreviewProps = {
110100
id: "1234567890",
111101
oid: "1234567890",
112102
type: "type",
113-
started: new Date().toISOString(),
103+
started: new Date(),
114104
object_type: "object_type",
115105
object_id: "object_id",
116106
file_path: "file_path",
117107
replica_storage: "replica_storage",
118108
},
119-
finished: new Date().toISOString(),
109+
finished: new Date(),
120110
} satisfies FailedBgJobEmailProps;
121111

122112
export default FailedBgJobEmail;

emails/emails/invite.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,8 @@ import { Template } from "../templates/btrix.js";
44
import {
55
differenceInDays,
66
formatDate,
7-
formatRelativeDate,
87
formatRelativeDateToParts,
98
offsetDays,
10-
reRenderDate,
119
} from "../lib/date.js";
1210
import { formatNumber } from "../lib/number.js";
1311
import { Button } from "../components/button.js";
@@ -21,7 +19,7 @@ export const schema = z.object({
2119
invite_url: z.string(),
2220
support_email: z.email().optional(),
2321
validity_period_days: z.number().int().positive().optional(),
24-
trial_end_date: z.string().nullish(),
22+
trial_end_date: z.coerce.date().nullish(),
2523
});
2624

2725
export type InviteUserEmailProps = z.infer<typeof schema>;
@@ -35,9 +33,7 @@ export const InviteUserEmail = ({
3533
validity_period_days = 7,
3634
trial_end_date,
3735
}: InviteUserEmailProps) => {
38-
const daysLeft = trial_end_date
39-
? differenceInDays(new Date(trial_end_date))
40-
: null;
36+
const daysLeft = trial_end_date ? differenceInDays(trial_end_date) : null;
4137
const relativeParts = daysLeft
4238
? formatRelativeDateToParts(daysLeft, "days")
4339
: null;
@@ -348,7 +344,7 @@ InviteUserEmail.PreviewProps = {
348344
invite_url: "https://app.browsertrix.com/invite-url-123-demo",
349345
support_email: "support@webrecorder.net",
350346
validity_period_days: 7,
351-
trial_end_date: offsetDays(7).toISOString(),
347+
trial_end_date: offsetDays(7),
352348
} satisfies InviteUserEmailProps;
353349

354350
export default InviteUserEmail;

emails/emails/subscription-cancel.tsx

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Heading, Link, Text } from "@react-email/components";
1+
import { Link, Text } from "@react-email/components";
22

33
import { Template } from "../templates/btrix.js";
44
import { formatDate, offsetDays } from "../lib/date.js";
@@ -12,23 +12,13 @@ export const schema = z.object({
1212
user_name: z.string(),
1313
org_name: z.string(),
1414
org_url: z.string().transform(trimTrailingSlash),
15-
cancel_date: z.string(),
15+
cancel_date: z.coerce.date(),
1616
survey_url: z.string().optional(),
1717
support_email: z.email().optional(),
1818
});
1919

2020
export type SubscriptionCancelEmailProps = z.infer<typeof schema>;
2121

22-
function reRenderDate(date: string) {
23-
try {
24-
const parsedDate = new Date(date);
25-
return formatDate(parsedDate);
26-
} catch (error) {
27-
console.error("Error parsing date:", error);
28-
return date;
29-
}
30-
}
31-
3222
export const SubscriptionCancelEmail = ({
3323
user_name,
3424
org_name,
@@ -37,7 +27,7 @@ export const SubscriptionCancelEmail = ({
3727
survey_url,
3828
support_email,
3929
}: SubscriptionCancelEmailProps) => {
40-
const date = reRenderDate(cancel_date);
30+
const date = formatDate(cancel_date);
4131
return (
4232
<Template
4333
preview={"Your Browsertrix subscription is cancelling"}
@@ -146,7 +136,7 @@ export const SubscriptionCancelEmail = ({
146136
SubscriptionCancelEmail.PreviewProps = {
147137
user_name: "Emma",
148138
org_name: "Emma’s Archives",
149-
cancel_date: offsetDays(7).toISOString(),
139+
cancel_date: offsetDays(7),
150140
survey_url: "https://example.com/survey",
151141
org_url: "https://dev.browsertrix.com/orgs/default-org",
152142
support_email: "support@webrecorder.net",
@@ -155,6 +145,6 @@ SubscriptionCancelEmail.PreviewProps = {
155145
export default SubscriptionCancelEmail;
156146

157147
export const subject = ({ cancel_date }: SubscriptionCancelEmailProps) => {
158-
const date = reRenderDate(cancel_date);
148+
const date = formatDate(cancel_date);
159149
return `Your Browsertrix subscription will be cancelled on ${date}`;
160150
};

emails/emails/trial-ending-soon.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import {
77
formatRelativeDate,
88
formatRelativeDateToParts,
99
offsetDays,
10-
reRenderDate,
1110
} from "../lib/date.js";
1211
import { Warning } from "../components/warning.js";
1312

@@ -18,7 +17,7 @@ export const schema = z.object({
1817
user_name: z.string(),
1918
org_name: z.string(),
2019
org_url: z.url().transform(trimTrailingSlash),
21-
trial_end_date: z.string(),
20+
trial_end_date: z.coerce.date(),
2221
behavior_on_trial_end: z.enum(["cancel", "continue"]).optional(),
2322
support_email: z.email().optional(),
2423
});
@@ -33,7 +32,7 @@ export const TrialEndingSoonEmail = ({
3332
behavior_on_trial_end = "continue",
3433
support_email,
3534
}: TrialEndingSoonEmailProps) => {
36-
const date = reRenderDate(trial_end_date);
35+
const date = formatDate(trial_end_date);
3736
const daysLeft = differenceInDays(new Date(trial_end_date));
3837
const relative = formatRelativeDate(daysLeft, "days");
3938
const relativeParts = formatRelativeDateToParts(daysLeft, "days");
@@ -182,7 +181,7 @@ export const TrialEndingSoonEmail = ({
182181
TrialEndingSoonEmail.PreviewProps = {
183182
user_name: "Emma",
184183
org_name: "Emma’s Archives",
185-
trial_end_date: offsetDays(7).toISOString(),
184+
trial_end_date: offsetDays(7),
186185
org_url: "https://dev.browsertrix.com/orgs/default-org",
187186
behavior_on_trial_end: "cancel",
188187
support_email: "support@webrecorder.net",
@@ -191,7 +190,7 @@ TrialEndingSoonEmail.PreviewProps = {
191190
export default TrialEndingSoonEmail;
192191

193192
export const subject = ({ trial_end_date }: TrialEndingSoonEmailProps) => {
194-
const date = reRenderDate(trial_end_date);
193+
const date = formatDate(trial_end_date);
195194
const daysLeft = differenceInDays(new Date(trial_end_date));
196195
const relative = formatRelativeDate(daysLeft, "days");
197196
return `Your Browsertrix trial ends ${relative}`;

emails/lib/date.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
export function parseDate(date: string) {
2-
try {
3-
return new Date(date);
4-
} catch (error) {
5-
console.error("Error parsing date:", error);
6-
throw new Error("Invalid date format");
7-
}
8-
}
9-
10-
export function reRenderDate(date: string) {
11-
try {
12-
const parsedDate = new Date(date);
13-
return formatDate(parsedDate);
14-
} catch (error) {
15-
console.error("Error parsing date:", error);
16-
return date;
17-
}
18-
}
19-
201
export const offsetDays = (days: number, from = new Date()) => {
212
const date = new Date(from);
223
date.setDate(date.getDate() + days);

0 commit comments

Comments
 (0)